diff options
Diffstat (limited to 'src/third_party/boost-1.68.0/boost/multiprecision/cpp_int/multiply.hpp')
-rw-r--r-- | src/third_party/boost-1.68.0/boost/multiprecision/cpp_int/multiply.hpp | 498 |
1 files changed, 0 insertions, 498 deletions
diff --git a/src/third_party/boost-1.68.0/boost/multiprecision/cpp_int/multiply.hpp b/src/third_party/boost-1.68.0/boost/multiprecision/cpp_int/multiply.hpp deleted file mode 100644 index 151b2294c75..00000000000 --- a/src/third_party/boost-1.68.0/boost/multiprecision/cpp_int/multiply.hpp +++ /dev/null @@ -1,498 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. 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_ -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_CPP_INT_MUL_HPP -#define BOOST_MP_CPP_INT_MUL_HPP - -namespace boost{ namespace multiprecision{ namespace backends{ - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4127) // conditional expression is constant -#endif - - template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if(!val) - { - result = static_cast<limb_type>(0); - return; - } - if((void*)&a != (void*)&result) - result.resize(a.size(), a.size()); - double_limb_type carry = 0; - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer p = result.limbs(); - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pe = result.limbs() + result.size(); - typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs(); - while(p != pe) - { - carry += static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(val); -#ifdef __MSVC_RUNTIME_CHECKS - *p = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - *p = static_cast<limb_type>(carry); -#endif - carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - ++p, ++pa; - } - if(carry) - { - unsigned i = result.size(); - result.resize(i + 1, i + 1); - if(result.size() > i) - result.limbs()[i] = static_cast<limb_type>(carry); - } - result.sign(a.sign()); - if(!cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable) - result.normalize(); -} - -// -// resize_for_carry forces a resize of the underlying buffer only if a previous request -// for "required" elements could possibly have failed, *and* we have checking enabled. -// This will cause an overflow error inside resize(): -// -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& /*result*/, unsigned /*required*/){} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, class Allocator1> -inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, checked, Allocator1>& result, unsigned required) -{ - if(result.size() < required) - result.resize(required, required); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - // Very simple long multiplication, only usable for small numbers of limb_type's - // but that's the typical use case for this type anyway: - // - // Special cases first: - // - unsigned as = a.size(); - unsigned bs = b.size(); - typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs(); - typename cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>::const_limb_pointer pb = b.limbs(); - if(as == 1) - { - bool s = b.sign() != a.sign(); - if(bs == 1) - { - result = static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(*pb); - } - else - { - limb_type l = *pa; - eval_multiply(result, b, l); - } - result.sign(s); - return; - } - if(bs == 1) - { - bool s = b.sign() != a.sign(); - limb_type l = *pb; - eval_multiply(result, a, l); - result.sign(s); - return; - } - - if((void*)&result == (void*)&a) - { - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(a); - eval_multiply(result, t, b); - return; - } - if((void*)&result == (void*)&b) - { - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(b); - eval_multiply(result, a, t); - return; - } - - result.resize(as + bs, as + bs - 1); - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs(); - - static const double_limb_type limb_max = ~static_cast<limb_type>(0u); - static const double_limb_type double_limb_max = ~static_cast<double_limb_type>(0u); - BOOST_STATIC_ASSERT(double_limb_max - 2 * limb_max >= limb_max * limb_max); - - double_limb_type carry = 0; - std::memset(pr, 0, result.size() * sizeof(limb_type)); - for(unsigned i = 0; i < as; ++i) - { - unsigned inner_limit = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable ? bs : (std::min)(result.size() - i, bs); - unsigned j; - for(j = 0; j < inner_limit; ++j) - { - BOOST_ASSERT(i+j < result.size()); -#if (!defined(__GLIBCXX__) && !defined(__GLIBCPP__)) || !BOOST_WORKAROUND(BOOST_GCC_VERSION, <= 50100) - BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized - || ((std::numeric_limits<double_limb_type>::max)() - carry - > - static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))); -#endif - carry += static_cast<double_limb_type>(pa[i]) * static_cast<double_limb_type>(pb[j]); - BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry >= pr[i+j])); - carry += pr[i + j]; -#ifdef __MSVC_RUNTIME_CHECKS - pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - pr[i + j] = static_cast<limb_type>(carry); -#endif - carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - BOOST_ASSERT(carry <= (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value)); - } - if(carry) - { - resize_for_carry(result, i + j + 1); // May throw if checking is enabled - if(i + j < result.size()) -#ifdef __MSVC_RUNTIME_CHECKS - pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - pr[i + j] = static_cast<limb_type>(carry); -#endif - } - carry = 0; - } - result.normalize(); - // - // Set the sign of the result: - // - result.sign(a.sign() != b.sign()); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - eval_multiply(result, result, a); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - eval_multiply(result, result, val); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if(val <= (std::numeric_limits<limb_type>::max)()) - { - eval_multiply(result, a, static_cast<limb_type>(val)); - } - else - { -#if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE) - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val); -#else - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t; - t = val; -#endif - eval_multiply(result, a, t); - } -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - eval_multiply(result, result, val); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if(val > 0) - eval_multiply(result, a, static_cast<limb_type>(val)); - else - { - eval_multiply(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(val))); - result.negate(); - } -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - eval_multiply(result, result, val); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if(val > 0) - { - if(val <= (std::numeric_limits<limb_type>::max)()) - { - eval_multiply(result, a, static_cast<limb_type>(val)); - return; - } - } - else if(val >= -static_cast<signed_double_limb_type>((std::numeric_limits<limb_type>::max)())) - { - eval_multiply(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(val))); - result.negate(); - return; - } -#if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE) - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val); -#else - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t; - t = val; -#endif - eval_multiply(result, a, t); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - eval_multiply(result, result, val); -} - -// -// Now over again for trivial cpp_int's: -// -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value) - >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.sign(result.sign() != o.sign()); - result.normalize(); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value) - >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.sign(a.sign() != b.sign()); - result.normalize(); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} - -// -// Special routines for multiplying two integers to obtain a multiprecision result: -// -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c< - !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - signed_double_limb_type a, signed_double_limb_type b) -{ - static const signed_double_limb_type mask = ~static_cast<limb_type>(0); - static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT; - bool s = false; - double_limb_type w, x, y, z; - if(a < 0) - { - a = -a; - s = true; - } - if(b < 0) - { - b = -b; - s = !s; - } - w = a & mask; - x = a >> limb_bits; - y = b & mask; - z = b >> limb_bits; - - result.resize(4, 4); - limb_type* pr = result.limbs(); - - double_limb_type carry = w * y; -#ifdef __MSVC_RUNTIME_CHECKS - pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - carry += w * z + x * y; - pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - carry += x * z; - pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - pr[3] = static_cast<limb_type>(carry >> limb_bits); -#else - pr[0] = static_cast<limb_type>(carry); - carry >>= limb_bits; - carry += w * z + x * y; - pr[1] = static_cast<limb_type>(carry); - carry >>= limb_bits; - carry += x * z; - pr[2] = static_cast<limb_type>(carry); - pr[3] = static_cast<limb_type>(carry >> limb_bits); -#endif - result.sign(s); - result.normalize(); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE typename enable_if_c< - !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - double_limb_type a, double_limb_type b) -{ - static const signed_double_limb_type mask = ~static_cast<limb_type>(0); - static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT; - - double_limb_type w, x, y, z; - w = a & mask; - x = a >> limb_bits; - y = b & mask; - z = b >> limb_bits; - - result.resize(4, 4); - limb_type* pr = result.limbs(); - - double_limb_type carry = w * y; -#ifdef __MSVC_RUNTIME_CHECKS - pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - carry += w * z; - pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry = x * y + pr[1]; - pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - carry += pr[2] + x * z; - pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - pr[3] = static_cast<limb_type>(carry >> limb_bits); -#else - pr[0] = static_cast<limb_type>(carry); - carry >>= limb_bits; - carry += w * z; - pr[1] = static_cast<limb_type>(carry); - carry >>= limb_bits; - pr[2] = static_cast<limb_type>(carry); - carry = x * y + pr[1]; - pr[1] = static_cast<limb_type>(carry); - carry >>= limb_bits; - carry += pr[2] + x * z; - pr[2] = static_cast<limb_type>(carry); - pr[3] = static_cast<limb_type>(carry >> limb_bits); -#endif - result.sign(false); - result.normalize(); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, - unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE typename enable_if_c< - !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value - && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value - >::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> const& a, - cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> const& b) -{ - typedef typename boost::multiprecision::detail::canonical<typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::local_limb_type, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::type canonical_type; - eval_multiply(result, static_cast<canonical_type>(*a.limbs()), static_cast<canonical_type>(*b.limbs())); - result.sign(a.sign() != b.sign()); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class SI> -BOOST_MP_FORCEINLINE typename enable_if_c<is_signed<SI>::value && (sizeof(SI) <= sizeof(signed_double_limb_type) / 2)>::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - SI a, SI b) -{ - result = static_cast<signed_double_limb_type>(a) * static_cast<signed_double_limb_type>(b); -} - -template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class UI> -BOOST_MP_FORCEINLINE typename enable_if_c<is_unsigned<UI>::value && (sizeof(UI) <= sizeof(signed_double_limb_type) / 2)>::type - eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - UI a, UI b) -{ - result = static_cast<double_limb_type>(a) * static_cast<double_limb_type>(b); -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -}}} // namespaces - -#endif |