/* boost random/detail/large_arithmetic.hpp header file
 *
 * Copyright Steven Watanabe 2011
 * Distributed under the Boost Software License, Version 1.0. (See
 * accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 *
 * See http://www.boost.org for most recent version including documentation.
 *
 * $Id: large_arithmetic.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
 */

#ifndef NDNBOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP
#define NDNBOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP

#include <ndnboost/cstdint.hpp>
#include <ndnboost/integer.hpp>
#include <ndnboost/limits.hpp>
#include <ndnboost/random/detail/integer_log2.hpp>

#include <ndnboost/random/detail/disable_warnings.hpp>

namespace ndnboost {
namespace random {
namespace detail {

struct div_t {
    ndnboost::uintmax_t quotient;
    ndnboost::uintmax_t remainder;
};

inline div_t muldivmod(ndnboost::uintmax_t a, ndnboost::uintmax_t b, ndnboost::uintmax_t m)
{
    static const int bits =
        ::std::numeric_limits< ::ndnboost::uintmax_t>::digits / 2;
    static const ::ndnboost::uintmax_t mask = (::ndnboost::uintmax_t(1) << bits) - 1;
    typedef ::ndnboost::uint_t<bits>::fast digit_t;

    int shift = std::numeric_limits< ::ndnboost::uintmax_t>::digits - 1
        - detail::integer_log2(m);

    a <<= shift;
    m <<= shift;

    digit_t product[4] = { 0, 0, 0, 0 };
    digit_t a_[2] = { digit_t(a & mask), digit_t((a >> bits) & mask) };
    digit_t b_[2] = { digit_t(b & mask), digit_t((b >> bits) & mask) };
    digit_t m_[2] = { digit_t(m & mask), digit_t((m >> bits) & mask) };

    // multiply a * b
    for(int i = 0; i < 2; ++i) {
        digit_t carry = 0;
        for(int j = 0; j < 2; ++j) {
            ::ndnboost::uint64_t temp = ::ndnboost::uintmax_t(a_[i]) * b_[j] +
                carry + product[i + j];
            product[i + j] = digit_t(temp & mask);
            carry = digit_t(temp >> bits);
        }
        if(carry != 0) {
            product[i + 2] += carry;
        }
    }

    digit_t quotient[2];

    if(m == 0) {
        div_t result = {
            ((::ndnboost::uintmax_t(product[3]) << bits) | product[2]),
            ((::ndnboost::uintmax_t(product[1]) << bits) | product[0]) >> shift,
        };
        return result;
    }

    // divide product / m
    for(int i = 3; i >= 2; --i) {
        ::ndnboost::uintmax_t temp =
            ::ndnboost::uintmax_t(product[i]) << bits | product[i - 1];

        digit_t q = digit_t((product[i] == m_[1]) ? mask : temp / m_[1]);

        ::ndnboost::uintmax_t rem =
            ((temp - ::ndnboost::uintmax_t(q) * m_[1]) << bits) + product[i - 2];

        ::ndnboost::uintmax_t diff = m_[0] * ::ndnboost::uintmax_t(q);

        int error = 0;
        if(diff > rem) {
            if(diff - rem > m) {
                error = 2;
            } else {
                error = 1;
            }
        }
        q -= error;
        rem = rem + error * m - diff;

        quotient[i - 2] = q;
        product[i] = 0;
        product[i-1] = (rem >> bits) & mask;
        product[i-2] = rem & mask;
    }

    div_t result = {
        ((::ndnboost::uintmax_t(quotient[1]) << bits) | quotient[0]),
        ((::ndnboost::uintmax_t(product[1]) << bits) | product[0]) >> shift,
    };
    return result;
}

inline ndnboost::uintmax_t muldiv(ndnboost::uintmax_t a, ndnboost::uintmax_t b, ndnboost::uintmax_t m)
{ return detail::muldivmod(a, b, m).quotient; }

inline ndnboost::uintmax_t mulmod(ndnboost::uintmax_t a, ndnboost::uintmax_t b, ndnboost::uintmax_t m)
{ return detail::muldivmod(a, b, m).remainder; }

} // namespace detail
} // namespace random
} // namespace ndnboost

#include <ndnboost/random/detail/enable_warnings.hpp>

#endif // NDNBOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP
