diff options
author | bugaevskiy <bugaevskiy@yandex-team.com> | 2022-08-23 11:05:33 +0300 |
---|---|---|
committer | bugaevskiy <bugaevskiy@yandex-team.com> | 2022-08-23 11:05:33 +0300 |
commit | 41e5df041415ca76c8839340ca9c2337ef2e87c1 (patch) | |
tree | f62a2c65613d378c6add970dcafa4bba5fe736d3 /contrib/restricted/boost | |
parent | 7fa4794ae863385f878e104405cd03f1066ec24c (diff) | |
download | ydb-41e5df041415ca76c8839340ca9c2337ef2e87c1.tar.gz |
Reimport boost/multiprecision as a separate project
Diffstat (limited to 'contrib/restricted/boost')
57 files changed, 35 insertions, 16932 deletions
diff --git a/contrib/restricted/boost/CMakeLists.txt b/contrib/restricted/boost/CMakeLists.txt index 448a9e53f3..7b89c14305 100644 --- a/contrib/restricted/boost/CMakeLists.txt +++ b/contrib/restricted/boost/CMakeLists.txt @@ -46,6 +46,7 @@ target_link_libraries(contrib-restricted-boost INTERFACE restricted-boost-mp11 restricted-boost-mpl restricted-boost-multi_array + restricted-boost-multiprecision restricted-boost-numeric_conversion restricted-boost-optional restricted-boost-parameter diff --git a/contrib/restricted/boost/boost/multiprecision/concepts/mp_number_archetypes.hpp b/contrib/restricted/boost/boost/multiprecision/concepts/mp_number_archetypes.hpp deleted file mode 100644 index b17eb121ae..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/concepts/mp_number_archetypes.hpp +++ /dev/null @@ -1,236 +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_ - -#ifndef BOOST_MATH_CONCEPTS_ER_HPP -#define BOOST_MATH_CONCEPTS_ER_HPP - -#include <iostream> -#include <sstream> -#include <iomanip> -#include <cmath> -#include <boost/cstdint.hpp> -#include <boost/multiprecision/number.hpp> -#include <boost/math/special_functions/fpclassify.hpp> -#include <boost/mpl/list.hpp> - -namespace boost{ -namespace multiprecision{ -namespace concepts{ - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4244) -#endif - -struct number_backend_float_architype -{ - typedef mpl::list<boost::long_long_type> signed_types; - typedef mpl::list<boost::ulong_long_type> unsigned_types; - typedef mpl::list<long double> float_types; - typedef int exponent_type; - - number_backend_float_architype() - { - m_value = 0; - std::cout << "Default construct" << std::endl; - } - number_backend_float_architype(const number_backend_float_architype& o) - { - std::cout << "Copy construct" << std::endl; - m_value = o.m_value; - } - number_backend_float_architype& operator = (const number_backend_float_architype& o) - { - m_value = o.m_value; - std::cout << "Assignment (" << m_value << ")" << std::endl; - return *this; - } - number_backend_float_architype& operator = (boost::ulong_long_type i) - { - m_value = i; - std::cout << "UInt Assignment (" << i << ")" << std::endl; - return *this; - } - number_backend_float_architype& operator = (boost::long_long_type i) - { - m_value = i; - std::cout << "Int Assignment (" << i << ")" << std::endl; - return *this; - } - number_backend_float_architype& operator = (long double d) - { - m_value = d; - std::cout << "long double Assignment (" << d << ")" << std::endl; - return *this; - } - number_backend_float_architype& operator = (const char* s) - { -#ifndef BOOST_NO_EXCEPTIONS - try - { -#endif - m_value = boost::lexical_cast<long double>(s); -#ifndef BOOST_NO_EXCEPTIONS - } - catch(const std::exception&) - { - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse input string: \"") + s + std::string("\" as a valid floating point number."))); - } -#endif - std::cout << "const char* Assignment (" << s << ")" << std::endl; - return *this; - } - void swap(number_backend_float_architype& o) - { - std::cout << "Swapping (" << m_value << " with " << o.m_value << ")" << std::endl; - std::swap(m_value, o.m_value); - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f)const - { - std::stringstream ss; - ss.flags(f); - if(digits) - ss.precision(digits); - else - ss.precision(std::numeric_limits<long double>::digits10 + 3); - boost::intmax_t i = m_value; - boost::uintmax_t u = m_value; - if(!(f & std::ios_base::scientific) && m_value == i) - ss << i; - else if(!(f & std::ios_base::scientific) && m_value == u) - ss << u; - else - ss << m_value; - std::string s = ss.str(); - std::cout << "Converting to string (" << s << ")" << std::endl; - return s; - } - void negate() - { - std::cout << "Negating (" << m_value << ")" << std::endl; - m_value = -m_value; - } - int compare(const number_backend_float_architype& o)const - { - std::cout << "Comparison" << std::endl; - return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0); - } - int compare(boost::long_long_type i)const - { - std::cout << "Comparison with int" << std::endl; - return m_value > i ? 1 : (m_value < i ? -1 : 0); - } - int compare(boost::ulong_long_type i)const - { - std::cout << "Comparison with unsigned" << std::endl; - return m_value > i ? 1 : (m_value < i ? -1 : 0); - } - int compare(long double d)const - { - std::cout << "Comparison with long double" << std::endl; - return m_value > d ? 1 : (m_value < d ? -1 : 0); - } - long double m_value; -}; - -inline void eval_add(number_backend_float_architype& result, const number_backend_float_architype& o) -{ - std::cout << "Addition (" << result.m_value << " += " << o.m_value << ")" << std::endl; - result.m_value += o.m_value; -} -inline void eval_subtract(number_backend_float_architype& result, const number_backend_float_architype& o) -{ - std::cout << "Subtraction (" << result.m_value << " -= " << o.m_value << ")" << std::endl; - result.m_value -= o.m_value; -} -inline void eval_multiply(number_backend_float_architype& result, const number_backend_float_architype& o) -{ - std::cout << "Multiplication (" << result.m_value << " *= " << o.m_value << ")" << std::endl; - result.m_value *= o.m_value; -} -inline void eval_divide(number_backend_float_architype& result, const number_backend_float_architype& o) -{ - std::cout << "Division (" << result.m_value << " /= " << o.m_value << ")" << std::endl; - result.m_value /= o.m_value; -} - -inline void eval_convert_to(boost::ulong_long_type* result, const number_backend_float_architype& val) -{ - *result = static_cast<boost::ulong_long_type>(val.m_value); -} -inline void eval_convert_to(boost::long_long_type* result, const number_backend_float_architype& val) -{ - *result = static_cast<boost::long_long_type>(val.m_value); -} -inline void eval_convert_to(long double* result, number_backend_float_architype& val) -{ - *result = val.m_value; -} - -inline void eval_frexp(number_backend_float_architype& result, const number_backend_float_architype& arg, int* exp) -{ - result = std::frexp(arg.m_value, exp); -} - -inline void eval_ldexp(number_backend_float_architype& result, const number_backend_float_architype& arg, int exp) -{ - result = std::ldexp(arg.m_value, exp); -} - -inline void eval_floor(number_backend_float_architype& result, const number_backend_float_architype& arg) -{ - result = std::floor(arg.m_value); -} - -inline void eval_ceil(number_backend_float_architype& result, const number_backend_float_architype& arg) -{ - result = std::ceil(arg.m_value); -} - -inline void eval_sqrt(number_backend_float_architype& result, const number_backend_float_architype& arg) -{ - result = std::sqrt(arg.m_value); -} - -inline int eval_fpclassify(const number_backend_float_architype& arg) -{ - return (boost::math::fpclassify)(arg.m_value); -} - -typedef boost::multiprecision::number<number_backend_float_architype> mp_number_float_architype; - -} // namespace - -template<> -struct number_category<concepts::number_backend_float_architype> : public mpl::int_<number_kind_floating_point>{}; - -}} // namespaces - -namespace std{ - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::concepts::number_backend_float_architype, ExpressionTemplates> > : public std::numeric_limits<long double> -{ - typedef std::numeric_limits<long double> base_type; - typedef boost::multiprecision::number<boost::multiprecision::concepts::number_backend_float_architype, ExpressionTemplates> number_type; -public: - static number_type (min)() BOOST_NOEXCEPT { return (base_type::min)(); } - static number_type (max)() BOOST_NOEXCEPT { return (base_type::max)(); } - static number_type lowest() BOOST_NOEXCEPT { return -(max)(); } - static number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); } - static number_type round_error() BOOST_NOEXCEPT { return base_type::round_error(); } - static number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); } - static number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); } - static number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); } - static number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); } -}; - -} - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_bin_float.hpp b/contrib/restricted/boost/boost/multiprecision/cpp_bin_float.hpp deleted file mode 100644 index 8d31e408cd..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/cpp_bin_float.hpp +++ /dev/null @@ -1,2025 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 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_ - -#ifndef BOOST_MATH_CPP_BIN_FLOAT_HPP -#define BOOST_MATH_CPP_BIN_FLOAT_HPP - -#include <boost/multiprecision/cpp_int.hpp> -#include <boost/multiprecision/integer.hpp> -#include <boost/math/special_functions/trunc.hpp> -#include <boost/multiprecision/detail/float_string_cvt.hpp> - -// -// Some includes we need from Boost.Math, since we rely on that library to provide these functions: -// -#include <boost/math/special_functions/asinh.hpp> -#include <boost/math/special_functions/acosh.hpp> -#include <boost/math/special_functions/atanh.hpp> -#include <boost/math/special_functions/cbrt.hpp> -#include <boost/math/special_functions/expm1.hpp> -#include <boost/math/special_functions/gamma.hpp> - -#ifdef BOOST_HAS_FLOAT128 -#include <quadmath.h> -#endif - -namespace boost{ namespace multiprecision{ namespace backends{ - -enum digit_base_type -{ - digit_base_2 = 2, - digit_base_10 = 10 -}; - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4522 6326) // multiple assignment operators specified, comparison of two constants -#endif - -namespace detail{ - -template <class U> -inline typename enable_if_c<is_unsigned<U>::value, bool>::type is_negative(U) { return false; } -template <class S> -inline typename disable_if_c<is_unsigned<S>::value, bool>::type is_negative(S s) { return s < 0; } - -} - -template <unsigned Digits, digit_base_type DigitBase = digit_base_10, class Allocator = void, class Exponent = int, Exponent MinExponent = 0, Exponent MaxExponent = 0> -class cpp_bin_float -{ -public: - static const unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + (((Digits * 1000uL) % 301) ? 2u : 1u); - typedef cpp_int_backend<is_void<Allocator>::value ? bit_count : 0, bit_count, is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> rep_type; - typedef cpp_int_backend<is_void<Allocator>::value ? 2 * bit_count : 0, 2 * bit_count, is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> double_rep_type; - - typedef typename rep_type::signed_types signed_types; - typedef typename rep_type::unsigned_types unsigned_types; - typedef boost::mpl::list<float, double, long double> float_types; - typedef Exponent exponent_type; - - static const exponent_type max_exponent_limit = boost::integer_traits<exponent_type>::const_max - 2 * static_cast<exponent_type>(bit_count); - static const exponent_type min_exponent_limit = boost::integer_traits<exponent_type>::const_min + 2 * static_cast<exponent_type>(bit_count); - - BOOST_STATIC_ASSERT_MSG(MinExponent >= min_exponent_limit, "Template parameter MinExponent is too negative for our internal logic to function correctly, sorry!"); - BOOST_STATIC_ASSERT_MSG(MaxExponent <= max_exponent_limit, "Template parameter MaxExponent is too large for our internal logic to function correctly, sorry!"); - BOOST_STATIC_ASSERT_MSG(MinExponent <= 0, "Template parameter MinExponent can not be positive!"); - BOOST_STATIC_ASSERT_MSG(MaxExponent >= 0, "Template parameter MaxExponent can not be negative!"); - - static const exponent_type max_exponent = MaxExponent == 0 ? max_exponent_limit : MaxExponent; - static const exponent_type min_exponent = MinExponent == 0 ? min_exponent_limit : MinExponent; - - static const exponent_type exponent_zero = max_exponent + 1; - static const exponent_type exponent_infinity = max_exponent + 2; - static const exponent_type exponent_nan = max_exponent + 3; - -private: - - rep_type m_data; - exponent_type m_exponent; - bool m_sign; -public: - cpp_bin_float() BOOST_MP_NOEXCEPT_IF(noexcept(rep_type())) : m_data(), m_exponent(exponent_zero), m_sign(false) {} - - cpp_bin_float(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(rep_type(std::declval<const rep_type&>()))) - : m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {} - - template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE> - cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE> &o, typename boost::enable_if_c<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = 0) - { - *this = o; - } - template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE> - explicit cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE> &o, typename boost::disable_if_c<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = 0) - : m_exponent(o.exponent()), m_sign(o.sign()) - { - *this = o; - } - template <class Float> - cpp_bin_float(const Float& f, - typename boost::enable_if_c< - (number_category<Float>::value == number_kind_floating_point) - && (std::numeric_limits<Float>::digits <= (int)bit_count) - && (std::numeric_limits<Float>::radix == 2) - && (std::numeric_limits<Float>::is_specialized) -#ifdef BOOST_HAS_FLOAT128 - && !boost::is_same<Float, __float128>::value -#endif - >::type const* = 0) - : m_data(), m_exponent(0), m_sign(false) - { - this->assign_float(f); - } - - template <class Float> - explicit cpp_bin_float(const Float& f, - typename boost::enable_if_c< - (number_category<Float>::value == number_kind_floating_point) - && (std::numeric_limits<Float>::digits > (int)bit_count) - && (std::numeric_limits<Float>::radix == 2) - && (std::numeric_limits<Float>::is_specialized) -#ifdef BOOST_HAS_FLOAT128 - && !boost::is_same<Float, __float128>::value -#endif ->::type const* = 0) - : m_data(), m_exponent(0), m_sign(false) - { - this->assign_float(f); - } -#ifdef BOOST_HAS_FLOAT128 - template <class Float> - cpp_bin_float(const Float& f, - typename boost::enable_if_c< - boost::is_same<Float, __float128>::value - && ((int)bit_count >= 113) - >::type const* = 0) - : m_data(), m_exponent(0), m_sign(false) - { - this->assign_float(f); - } - template <class Float> - explicit cpp_bin_float(const Float& f, - typename boost::enable_if_c< - boost::is_same<Float, __float128>::value - && ((int)bit_count < 113) - >::type const* = 0) - : m_data(), m_exponent(0), m_sign(false) - { - this->assign_float(f); - } -#endif - cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>())) - { - m_data = o.m_data; - m_exponent = o.m_exponent; - m_sign = o.m_sign; - return *this; - } - - template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE> - cpp_bin_float& operator=(const cpp_bin_float<D, B, A, E, MinE, MaxE> &f) - { - switch(eval_fpclassify(f)) - { - case FP_ZERO: - m_data = limb_type(0); - m_sign = f.sign(); - m_exponent = exponent_zero; - break; - case FP_NAN: - m_data = limb_type(0); - m_sign = false; - m_exponent = exponent_nan; - break;; - case FP_INFINITE: - m_data = limb_type(0); - m_sign = f.sign(); - m_exponent = exponent_infinity; - break; - default: - typename cpp_bin_float<D, B, A, E, MinE, MaxE>::rep_type b(f.bits()); - this->exponent() = f.exponent() + (E)bit_count - (E)cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count; - this->sign() = f.sign(); - copy_and_round(*this, b); - } - return *this; - } -#ifdef BOOST_HAS_FLOAT128 - template <class Float> - typename boost::enable_if_c< - (number_category<Float>::value == number_kind_floating_point) - //&& (std::numeric_limits<Float>::digits <= (int)bit_count) - && ((std::numeric_limits<Float>::radix == 2) || (boost::is_same<Float, __float128>::value)), cpp_bin_float&>::type - operator=(const Float& f) -#else - template <class Float> - typename boost::enable_if_c< - (number_category<Float>::value == number_kind_floating_point) - //&& (std::numeric_limits<Float>::digits <= (int)bit_count) - && (std::numeric_limits<Float>::radix == 2), cpp_bin_float&>::type - operator=(const Float& f) -#endif - { - return assign_float(f); - } - -#ifdef BOOST_HAS_FLOAT128 - template <class Float> - typename boost::enable_if_c<boost::is_same<Float, __float128>::value, cpp_bin_float& >::type assign_float(Float f) - { - using default_ops::eval_add; - typedef typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type bf_int_type; - if(f == 0) - { - m_data = limb_type(0); - m_sign = (signbitq(f) > 0); - m_exponent = exponent_zero; - return *this; - } - else if(isnanq(f)) - { - m_data = limb_type(0); - m_sign = false; - m_exponent = exponent_nan; - return *this; - } - else if(isinfq(f)) - { - m_data = limb_type(0); - m_sign = (f < 0); - m_exponent = exponent_infinity; - return *this; - } - if(f < 0) - { - *this = -f; - this->negate(); - return *this; - } - - typedef typename mpl::front<unsigned_types>::type ui_type; - m_data = static_cast<ui_type>(0u); - m_sign = false; - m_exponent = 0; - - static const int bits = sizeof(int) * CHAR_BIT - 1; - int e; - f = frexpq(f, &e); - while(f) - { - f = ldexpq(f, bits); - e -= bits; - int ipart = (int)truncq(f); - f -= ipart; - m_exponent += bits; - cpp_bin_float t; - t = static_cast<bf_int_type>(ipart); - eval_add(*this, t); - } - m_exponent += static_cast<Exponent>(e); - return *this; - } -#endif -#ifdef BOOST_HAS_FLOAT128 - template <class Float> - typename boost::enable_if_c<is_floating_point<Float>::value && !is_same<Float, __float128>::value, cpp_bin_float&>::type assign_float(Float f) -#else - template <class Float> - typename boost::enable_if_c<is_floating_point<Float>::value, cpp_bin_float&>::type assign_float(Float f) -#endif - { - BOOST_MATH_STD_USING - using default_ops::eval_add; - typedef typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type bf_int_type; - - switch((boost::math::fpclassify)(f)) - { - case FP_ZERO: - m_data = limb_type(0); - m_sign = ((boost::math::signbit)(f) > 0); - m_exponent = exponent_zero; - return *this; - case FP_NAN: - m_data = limb_type(0); - m_sign = false; - m_exponent = exponent_nan; - return *this; - case FP_INFINITE: - m_data = limb_type(0); - m_sign = (f < 0); - m_exponent = exponent_infinity; - return *this; - } - if(f < 0) - { - *this = -f; - this->negate(); - return *this; - } - - typedef typename mpl::front<unsigned_types>::type ui_type; - m_data = static_cast<ui_type>(0u); - m_sign = false; - m_exponent = 0; - - static const int bits = sizeof(int) * CHAR_BIT - 1; - int e; - f = frexp(f, &e); - while(f) - { - f = ldexp(f, bits); - e -= bits; -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - int ipart = itrunc(f); -#else - int ipart = static_cast<int>(f); -#endif - f -= ipart; - m_exponent += bits; - cpp_bin_float t; - t = static_cast<bf_int_type>(ipart); - eval_add(*this, t); - } - m_exponent += static_cast<Exponent>(e); - return *this; - } - - template <class Float> - typename boost::enable_if_c< - (number_category<Float>::value == number_kind_floating_point) - && !boost::is_floating_point<Float>::value - /*&& (std::numeric_limits<number<Float> >::radix == 2)*/, - cpp_bin_float&>::type assign_float(Float f) - { - BOOST_MATH_STD_USING - using default_ops::eval_add; - using default_ops::eval_get_sign; - using default_ops::eval_convert_to; - using default_ops::eval_subtract; - - typedef typename boost::multiprecision::detail::canonical<int, Float>::type f_int_type; - typedef typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type bf_int_type; - - switch(eval_fpclassify(f)) - { - case FP_ZERO: - m_data = limb_type(0); - m_sign = ((boost::math::signbit)(f) > 0); - m_exponent = exponent_zero; - return *this; - case FP_NAN: - m_data = limb_type(0); - m_sign = false; - m_exponent = exponent_nan; - return *this; - case FP_INFINITE: - m_data = limb_type(0); - m_sign = (f < 0); - m_exponent = exponent_infinity; - return *this; - } - if(eval_get_sign(f) < 0) - { - f.negate(); - *this = f; - this->negate(); - return *this; - } - - typedef typename mpl::front<unsigned_types>::type ui_type; - m_data = static_cast<ui_type>(0u); - m_sign = false; - m_exponent = 0; - - static const int bits = sizeof(int) * CHAR_BIT - 1; - int e; - eval_frexp(f, f, &e); - while(eval_get_sign(f) != 0) - { - eval_ldexp(f, f, bits); - e -= bits; - int ipart; - eval_convert_to(&ipart, f); - eval_subtract(f, static_cast<f_int_type>(ipart)); - m_exponent += bits; - eval_add(*this, static_cast<bf_int_type>(ipart)); - } - m_exponent += e; - if(m_exponent > max_exponent) - m_exponent = exponent_infinity; - if(m_exponent < min_exponent) - { - m_data = limb_type(0u); - m_exponent = exponent_zero; - m_sign = ((boost::math::signbit)(f) > 0); - } - else if(eval_get_sign(m_data) == 0) - { - m_exponent = exponent_zero; - m_sign = ((boost::math::signbit)(f) > 0); - } - return *this; - } - - template <class I> - typename boost::enable_if<is_integral<I>, cpp_bin_float&>::type operator=(const I& i) - { - using default_ops::eval_bit_test; - if(!i) - { - m_data = static_cast<limb_type>(0); - m_exponent = exponent_zero; - m_sign = false; - } - else - { - typedef typename make_unsigned<I>::type ui_type; - ui_type fi = static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(i)); - typedef typename boost::multiprecision::detail::canonical<ui_type, rep_type>::type ar_type; - m_data = static_cast<ar_type>(fi); - unsigned shift = msb(fi); - if(shift >= bit_count) - { - m_exponent = static_cast<Exponent>(shift); - m_data = static_cast<ar_type>(fi >> (shift + 1 - bit_count)); - } - else - { - m_exponent = static_cast<Exponent>(shift); - eval_left_shift(m_data, bit_count - shift - 1); - } - BOOST_ASSERT(eval_bit_test(m_data, bit_count-1)); - m_sign = detail::is_negative(i); - } - return *this; - } - - cpp_bin_float& operator=(const char *s); - - void swap(cpp_bin_float &o) BOOST_NOEXCEPT - { - m_data.swap(o.m_data); - std::swap(m_exponent, o.m_exponent); - std::swap(m_sign, o.m_sign); - } - - std::string str(std::streamsize dig, std::ios_base::fmtflags f) const; - - void negate() - { - if(m_exponent != exponent_nan) - m_sign = !m_sign; - } - - int compare(const cpp_bin_float &o) const BOOST_NOEXCEPT - { - if(m_sign != o.m_sign) - return (m_exponent == exponent_zero) && (m_exponent == o.m_exponent) ? 0 : m_sign ? -1 : 1; - int result; - if(m_exponent == exponent_nan) - return -1; - else if(m_exponent != o.m_exponent) - { - if(m_exponent == exponent_zero) - result = -1; - else if(o.m_exponent == exponent_zero) - result = 1; - else - result = m_exponent > o.m_exponent ? 1 : -1; - } - else - result = m_data.compare(o.m_data); - if(m_sign) - result = -result; - return result; - } - template <class A> - int compare(const A& o) const BOOST_NOEXCEPT - { - cpp_bin_float b; - b = o; - return compare(b); - } - - rep_type& bits() { return m_data; } - const rep_type& bits()const { return m_data; } - exponent_type& exponent() { return m_exponent; } - const exponent_type& exponent()const { return m_exponent; } - bool& sign() { return m_sign; } - const bool& sign()const { return m_sign; } - void check_invariants() - { - using default_ops::eval_bit_test; - using default_ops::eval_is_zero; - if((m_exponent <= max_exponent) && (m_exponent >= min_exponent)) - { - BOOST_ASSERT(eval_bit_test(m_data, bit_count - 1)); - } - else - { - BOOST_ASSERT(m_exponent > max_exponent); - BOOST_ASSERT(m_exponent <= exponent_nan); - BOOST_ASSERT(eval_is_zero(m_data)); - } - } - template<class Archive> - void serialize(Archive & ar, const unsigned int /*version*/) - { - ar & m_data; - ar & m_exponent; - ar & m_sign; - } -}; - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Int> -inline void copy_and_round(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, Int &arg, int bits_to_keep = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) -{ - // Precondition: exponent of res must have been set before this function is called - // as we may need to adjust it based on how many bits_to_keep in arg are set. - using default_ops::eval_msb; - using default_ops::eval_lsb; - using default_ops::eval_left_shift; - using default_ops::eval_bit_test; - using default_ops::eval_right_shift; - using default_ops::eval_increment; - using default_ops::eval_get_sign; - - // cancellation may have resulted in arg being all zeros: - if(eval_get_sign(arg) == 0) - { - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero; - res.sign() = false; - res.bits() = static_cast<limb_type>(0u); - return; - } - int msb = eval_msb(arg); - if(static_cast<int>(bits_to_keep) > msb + 1) - { - // Must have had cancellation in subtraction, - // or be converting from a narrower type, so shift left: - res.bits() = arg; - eval_left_shift(res.bits(), bits_to_keep - msb - 1); - res.exponent() -= static_cast<Exponent>(bits_to_keep - msb - 1); - } - else if(static_cast<int>(bits_to_keep) < msb + 1) - { - // We have more bits_to_keep than we need, so round as required, - // first get the rounding bit: - bool roundup = eval_bit_test(arg, msb - bits_to_keep); - // Then check for a tie: - if(roundup && (msb - bits_to_keep == (int)eval_lsb(arg))) - { - // Ties round towards even: - if(!eval_bit_test(arg, msb - bits_to_keep + 1)) - roundup = false; - } - // Shift off the bits_to_keep we don't need: - eval_right_shift(arg, msb - bits_to_keep + 1); - res.exponent() += static_cast<Exponent>(msb - bits_to_keep + 1); - if(roundup) - { - eval_increment(arg); - if(bits_to_keep) - { - if(eval_bit_test(arg, bits_to_keep)) - { - // This happens very very rairly, all the bits left after - // truncation must be 1's and we're rounding up an order of magnitude: - eval_right_shift(arg, 1u); - ++res.exponent(); - } - } - else - { - // We get here when bits_to_keep is zero but we're rounding up, - // as a result we end up with a single digit that is a 1: - ++bits_to_keep; - } - } - if(bits_to_keep != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - { - // Normalize result when we're rounding to fewer bits than we can hold, only happens in conversions - // to narrower types: - eval_left_shift(arg, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - bits_to_keep); - res.exponent() -= static_cast<Exponent>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - bits_to_keep); - } - res.bits() = arg; - } - else - { - res.bits() = arg; - } - if(!bits_to_keep && !res.bits().limbs()[0]) - { - // We're keeping zero bits and did not round up, so result is zero: - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero; - return; - } - // Result must be normalized: - BOOST_ASSERT(((int)eval_msb(res.bits()) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)); - - if(res.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) - { - // Overflow: - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity; - res.bits() = static_cast<limb_type>(0u); - } - else if(res.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent) - { - // Underflow: - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero; - res.bits() = static_cast<limb_type>(0u); - } -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void do_eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b) -{ - if(a.exponent() < b.exponent()) - { - bool s = a.sign(); - do_eval_add(res, b, a); - if(res.sign() != s) - res.negate(); - return; - } - - using default_ops::eval_add; - using default_ops::eval_bit_test; - - typedef typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type exponent_type; - - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt; - - // Special cases first: - switch(a.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - { - bool s = a.sign(); - res = b; - res.sign() = s; - return; - } - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan) - res = b; - else - res = a; - return; // result is still infinite. - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = a; - return; // result is still a NaN. - } - switch(b.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - res = a; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - res = b; - if(res.sign()) - res.negate(); - return; // result is infinite. - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = b; - return; // result is a NaN. - } - - BOOST_STATIC_ASSERT(boost::integer_traits<exponent_type>::const_max - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent); - - bool s = a.sign(); - dt = a.bits(); - if(a.exponent() > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + b.exponent()) - { - res.exponent() = a.exponent(); - } - else - { - exponent_type e_diff = a.exponent() - b.exponent(); - BOOST_ASSERT(e_diff >= 0); - eval_left_shift(dt, e_diff); - res.exponent() = a.exponent() - e_diff; - eval_add(dt, b.bits()); - } - - copy_and_round(res, dt); - res.check_invariants(); - if(res.sign() != s) - res.negate(); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void do_eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b) -{ - using default_ops::eval_subtract; - using default_ops::eval_bit_test; - using default_ops::eval_decrement; - - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt; - - // Special cases first: - switch(a.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan) - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - else - { - bool s = a.sign(); - res = b; - if(res.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero) - res.sign() = false; - else if(res.sign() == s) - res.negate(); - } - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - if((b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan) || (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity)) - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - else - res = a; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = a; - return; // result is still a NaN. - } - switch(b.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - res = a; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity; - res.sign() = !a.sign(); - res.bits() = static_cast<limb_type>(0u); - return; // result is a NaN. - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = b; - return; // result is still a NaN. - } - - bool s = a.sign(); - if((a.exponent() > b.exponent()) || ((a.exponent() == b.exponent()) && a.bits().compare(b.bits()) >= 0)) - { - dt = a.bits(); - if(a.exponent() <= (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + b.exponent()) - { - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type e_diff = a.exponent() - b.exponent(); - eval_left_shift(dt, e_diff); - res.exponent() = a.exponent() - e_diff; - eval_subtract(dt, b.bits()); - } - else if(a.exponent() == (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + b.exponent() + 1) - { - if(eval_lsb(b.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1) - { - eval_left_shift(dt, 1); - eval_decrement(dt); - res.exponent() = a.exponent() - 1; - } - else - res.exponent() = a.exponent(); - } - else - res.exponent() = a.exponent(); - } - else - { - dt = b.bits(); - if(b.exponent() <= (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + a.exponent()) - { - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type e_diff = a.exponent() - b.exponent(); - eval_left_shift(dt, -e_diff); - res.exponent() = b.exponent() + e_diff; - eval_subtract(dt, a.bits()); - } - else if(b.exponent() == (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + a.exponent() + 1) - { - if(eval_lsb(a.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1) - { - eval_left_shift(dt, 1); - eval_decrement(dt); - res.exponent() = b.exponent() - 1; - } - else - res.exponent() = b.exponent(); - } - else - res.exponent() = b.exponent(); - s = !s; - } - - copy_and_round(res, dt); - if(res.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero) - res.sign() = false; - else if(res.sign() != s) - res.negate(); - res.check_invariants(); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b) -{ - if(a.sign() == b.sign()) - do_eval_add(res, a, b); - else - do_eval_subtract(res, a, b); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a) -{ - return eval_add(res, res, a); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b) -{ - if(a.sign() != b.sign()) - do_eval_add(res, a, b); - else - do_eval_subtract(res, a, b); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a) -{ - return eval_subtract(res, res, a); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b) -{ - using default_ops::eval_bit_test; - using default_ops::eval_multiply; - - // Special cases first: - switch(a.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - { - if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan) - res = b; - else if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity) - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - else - { - bool s = a.sign() != b.sign(); - res = a; - res.sign() = s; - } - return; - } - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - switch(b.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - break; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = b; - break; - default: - bool s = a.sign() != b.sign(); - res = a; - res.sign() = s; - break; - } - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = a; - return; - } - if(b.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) - { - bool s = a.sign() != b.sign(); - res = b; - res.sign() = s; - return; - } - if((a.exponent() > 0) && (b.exponent() > 0)) - { - if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + 2 - a.exponent() < b.exponent()) - { - // We will certainly overflow: - bool s = a.sign() != b.sign(); - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity; - res.sign() = s; - res.bits() = static_cast<limb_type>(0u); - return; - } - } - if((a.exponent() < 0) && (b.exponent() < 0)) - { - if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - 2 - a.exponent() > b.exponent()) - { - // We will certainly underflow: - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero; - res.sign() = a.sign() != b.sign(); - res.bits() = static_cast<limb_type>(0u); - return; - } - } - - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt; - eval_multiply(dt, a.bits(), b.bits()); - res.exponent() = a.exponent() + b.exponent() - (Exponent)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1; - copy_and_round(res, dt); - res.check_invariants(); - res.sign() = a.sign() != b.sign(); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a) -{ - eval_multiply(res, res, a); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U> -inline typename enable_if_c<is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const U &b) -{ - using default_ops::eval_bit_test; - using default_ops::eval_multiply; - - // Special cases first: - switch(a.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - { - bool s = a.sign(); - res = a; - res.sign() = s; - return; - } - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - if(b == 0) - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - else - res = a; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = a; - return; - } - - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt; - typedef typename boost::multiprecision::detail::canonical<U, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::type canon_ui_type; - eval_multiply(dt, a.bits(), static_cast<canon_ui_type>(b)); - res.exponent() = a.exponent(); - copy_and_round(res, dt); - res.check_invariants(); - res.sign() = a.sign(); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U> -inline typename enable_if_c<is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const U &b) -{ - eval_multiply(res, res, b); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S> -inline typename enable_if_c<is_signed<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const S &b) -{ - typedef typename make_unsigned<S>::type ui_type; - eval_multiply(res, a, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(b))); - if(b < 0) - res.negate(); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S> -inline typename enable_if_c<is_signed<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const S &b) -{ - eval_multiply(res, res, b); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &v) -{ -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:6326) // comparison of two constants -#endif - using default_ops::eval_subtract; - using default_ops::eval_qr; - using default_ops::eval_bit_test; - using default_ops::eval_get_sign; - using default_ops::eval_increment; - - // - // Special cases first: - // - switch(u.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - { - switch(v.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - return; - } - bool s = u.sign() != v.sign(); - res = u; - res.sign() = s; - return; - } - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - { - switch(v.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - return; - } - bool s = u.sign() != v.sign(); - res = u; - res.sign() = s; - return; - } - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - return; - } - switch(v.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - { - bool s = u.sign() != v.sign(); - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend(); - res.sign() = s; - return; - } - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero; - res.bits() = limb_type(0); - res.sign() = u.sign() != v.sign(); - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - return; - } - - // We can scale u and v so that both are integers, then perform integer - // division to obtain quotient q and remainder r, such that: - // - // q * v + r = u - // - // and hense: - // - // q + r/v = u/v - // - // From this, assuming q has cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - // bits we only need to determine whether - // r/v is less than, equal to, or greater than 0.5 to determine rounding - - // this we can do with a shift and comparison. - // - // We can set the exponent and sign of the result up front: - // - if((v.exponent() < 0) && (u.exponent() > 0)) - { - // Check for overflow: - if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + v.exponent() < u.exponent() - 1) - { - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity; - res.sign() = u.sign() != v.sign(); - res.bits() = static_cast<limb_type>(0u); - return; - } - } - else if((v.exponent() > 0) && (u.exponent() < 0)) - { - // Check for underflow: - if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent + v.exponent() > u.exponent()) - { - // We will certainly underflow: - res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero; - res.sign() = u.sign() != v.sign(); - res.bits() = static_cast<limb_type>(0u); - return; - } - } - res.exponent() = u.exponent() - v.exponent() - 1; - res.sign() = u.sign() != v.sign(); - // - // Now get the quotient and remainder: - // - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), t2(v.bits()), q, r; - eval_left_shift(t, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count); - eval_qr(t, t2, q, r); - // - // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" - // or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant - // bits in q. - // - static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT; - if(eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)) - { - // - // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 bits, - // so we already have rounding info, - // we just need to changes things if the last bit is 1 and either the - // remainder is non-zero (ie we do not have a tie) or the quotient would - // be odd if it were shifted to the correct number of bits (ie a tiebreak). - // - BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)); - if((q.limbs()[0] & 1u) && (eval_get_sign(r) || (q.limbs()[0] & 2u))) - { - eval_increment(q); - } - } - else - { - // - // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" bits in q. - // Get rounding info, which we can get by comparing 2r with v. - // We want to call copy_and_round to handle rounding and general cleanup, - // so we'll left shift q and add some fake digits on the end to represent - // how we'll be rounding. - // - BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)); - static const unsigned lshift = (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits) ? 2 : limb_bits; - eval_left_shift(q, lshift); - res.exponent() -= lshift; - eval_left_shift(r, 1u); - int c = r.compare(v.bits()); - if(c == 0) - q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1); - else if(c > 0) - q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u); - } - copy_and_round(res, q); -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - eval_divide(res, res, arg); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U> -inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const U &v) -{ -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:6326) // comparison of two constants -#endif - using default_ops::eval_subtract; - using default_ops::eval_qr; - using default_ops::eval_bit_test; - using default_ops::eval_get_sign; - using default_ops::eval_increment; - - // - // Special cases first: - // - switch(u.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - { - if(v == 0) - { - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - return; - } - bool s = u.sign() != (v < 0); - res = u; - res.sign() = s; - return; - } - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - res = u; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - return; - } - if(v == 0) - { - bool s = u.sign(); - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend(); - res.sign() = s; - return; - } - - // We can scale u and v so that both are integers, then perform integer - // division to obtain quotient q and remainder r, such that: - // - // q * v + r = u - // - // and hense: - // - // q + r/v = u/v - // - // From this, assuming q has "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, we only need to determine whether - // r/v is less than, equal to, or greater than 0.5 to determine rounding - - // this we can do with a shift and comparison. - // - // We can set the exponent and sign of the result up front: - // - int gb = msb(v); - res.exponent() = u.exponent() - static_cast<Exponent>(gb) - static_cast<Exponent>(1); - res.sign() = u.sign(); - // - // Now get the quotient and remainder: - // - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), q, r; - eval_left_shift(t, gb + 1); - eval_qr(t, number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v), q, r); - // - // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q. - // - static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT; - if(eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)) - { - // - // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, so we already have rounding info, - // we just need to changes things if the last bit is 1 and the - // remainder is non-zero (ie we do not have a tie). - // - BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)); - if((q.limbs()[0] & 1u) && eval_get_sign(r)) - { - eval_increment(q); - } - } - else - { - // - // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q. - // Get rounding info, which we can get by comparing 2r with v. - // We want to call copy_and_round to handle rounding and general cleanup, - // so we'll left shift q and add some fake cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count on the end to represent - // how we'll be rounding. - // - BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)); - static const unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits; - eval_left_shift(q, lshift); - res.exponent() -= lshift; - eval_left_shift(r, 1u); - int c = r.compare(number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v)); - if(c == 0) - q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1); - else if(c > 0) - q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u); - } - copy_and_round(res, q); -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U> -inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const U &v) -{ - eval_divide(res, res, v); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S> -inline typename enable_if_c<is_signed<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const S &v) -{ - typedef typename make_unsigned<S>::type ui_type; - eval_divide(res, u, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(v))); - if(v < 0) - res.negate(); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S> -inline typename enable_if_c<is_signed<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const S &v) -{ - eval_divide(res, res, v); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline int eval_get_sign(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero ? 0 : arg.sign() ? -1 : 1; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline bool eval_is_zero(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline bool eval_eq(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b) -{ - if(a.exponent() == b.exponent()) - { - if(a.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero) - return true; - return (a.sign() == b.sign()) - && (a.bits().compare(b.bits()) == 0) - && (a.exponent() != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan); - } - return false; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_convert_to(boost::long_long_type *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - switch(arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - *res = 0; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - *res = (std::numeric_limits<boost::long_long_type>::max)(); - if(arg.sign()) - *res = -*res; - return; - } - typedef typename mpl::if_c < sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type > ::type shift_type; - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits()); - shift_type shift - = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent(); - if(shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1) - { - *res = 0; - return; - } - if(arg.sign() && (arg.compare((std::numeric_limits<boost::long_long_type>::min)()) <= 0)) - { - *res = (std::numeric_limits<boost::long_long_type>::min)(); - return; - } - else if(!arg.sign() && (arg.compare((std::numeric_limits<boost::long_long_type>::max)()) >= 0)) - { - *res = (std::numeric_limits<boost::long_long_type>::max)(); - return; - } - - if (shift < 0) - { - if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - shift <= std::numeric_limits<boost::long_long_type>::digits) - { - // We have more bits in long_long_type than the float, so it's OK to left shift: - eval_convert_to(res, man); - *res <<= -shift; - } - else - { - *res = (std::numeric_limits<boost::long_long_type>::max)(); - return; - } - } - else - { - eval_right_shift(man, shift); - eval_convert_to(res, man); - } - if(arg.sign()) - { - *res = -*res; - } -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_convert_to(boost::ulong_long_type *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - switch(arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - *res = 0; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - *res = (std::numeric_limits<boost::ulong_long_type>::max)(); - return; - } - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits()); - typedef typename mpl::if_c < sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type > ::type shift_type; - shift_type shift - = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent(); - if(shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1) - { - *res = 0; - return; - } - else if(shift < 0) - { - if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - shift <= std::numeric_limits<boost::ulong_long_type>::digits) - { - // We have more bits in ulong_long_type than the float, so it's OK to left shift: - eval_convert_to(res, man); - *res <<= -shift; - return; - } - *res = (std::numeric_limits<boost::ulong_long_type>::max)(); - return; - } - eval_right_shift(man, shift); - eval_convert_to(res, man); -} - -template <class Float, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline typename boost::enable_if_c<boost::is_float<Float>::value>::type eval_convert_to(Float *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &original_arg) -{ - typedef cpp_bin_float<std::numeric_limits<Float>::digits, digit_base_2, void, Exponent, MinE, MaxE> conv_type; - typedef typename common_type<typename conv_type::exponent_type, int>::type common_exp_type; - // - // Special cases first: - // - switch(original_arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - *res = 0; - if(original_arg.sign()) - *res = -*res; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - *res = std::numeric_limits<Float>::quiet_NaN(); - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - *res = (std::numeric_limits<Float>::infinity)(); - if(original_arg.sign()) - *res = -*res; - return; - } - // - // Check for super large exponent that must be converted to infinity: - // - if(original_arg.exponent() > std::numeric_limits<Float>::max_exponent) - { - *res = std::numeric_limits<Float>::has_infinity ? std::numeric_limits<Float>::infinity() : (std::numeric_limits<Float>::max)(); - if(original_arg.sign()) - *res = -*res; - return; - } - // - // Figure out how many digits we will have in our result, - // allowing for a possibly denormalized result: - // - common_exp_type digits_to_round_to = std::numeric_limits<Float>::digits; - if(original_arg.exponent() < std::numeric_limits<Float>::min_exponent - 1) - { - common_exp_type diff = original_arg.exponent(); - diff -= std::numeric_limits<Float>::min_exponent - 1; - digits_to_round_to += diff; - } - if(digits_to_round_to < 0) - { - // Result must be zero: - *res = 0; - if(original_arg.sign()) - *res = -*res; - return; - } - // - // Perform rounding first, then afterwards extract the digits: - // - cpp_bin_float<std::numeric_limits<Float>::digits, digit_base_2, Allocator, Exponent, MinE, MaxE> arg; - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type bits(original_arg.bits()); - arg.exponent() = original_arg.exponent(); - copy_and_round(arg, bits, (int)digits_to_round_to); - common_exp_type e = arg.exponent(); - e -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1; - static const unsigned limbs_needed = std::numeric_limits<Float>::digits / (sizeof(*arg.bits().limbs()) * CHAR_BIT) - + (std::numeric_limits<Float>::digits % (sizeof(*arg.bits().limbs()) * CHAR_BIT) ? 1 : 0); - unsigned first_limb_needed = arg.bits().size() - limbs_needed; - *res = 0; - e += first_limb_needed * sizeof(*arg.bits().limbs()) * CHAR_BIT; - while(first_limb_needed < arg.bits().size()) - { - *res += std::ldexp(static_cast<Float>(arg.bits().limbs()[first_limb_needed]), static_cast<int>(e)); - ++first_limb_needed; - e += sizeof(*arg.bits().limbs()) * CHAR_BIT; - } - if(original_arg.sign()) - *res = -*res; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, Exponent *e) -{ - switch(arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - *e = 0; - res = arg; - return; - } - res = arg; - *e = arg.exponent() + 1; - res.exponent() = -1; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I> -inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, I *pe) -{ - Exponent e; - eval_frexp(res, arg, &e); - if((e > (std::numeric_limits<I>::max)()) || (e < (std::numeric_limits<I>::min)())) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Exponent was outside of the range of the argument type to frexp.")); - } - *pe = static_cast<I>(e); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, Exponent e) -{ - switch(arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - res = arg; - return; - } - if((e > 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent - e < arg.exponent())) - { - // Overflow: - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend(); - res.sign() = arg.sign(); - } - else if((e < 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - e > arg.exponent())) - { - // Underflow: - res = limb_type(0); - } - else - { - res = arg; - res.exponent() += e; - } -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I> -inline typename enable_if_c<is_unsigned<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, I e) -{ - typedef typename make_signed<I>::type si_type; - if(e > static_cast<I>((std::numeric_limits<si_type>::max)())) - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend(); - else - eval_ldexp(res, arg, static_cast<si_type>(e)); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I> -inline typename enable_if_c<is_signed<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, I e) -{ - if((e > (std::numeric_limits<Exponent>::max)()) || (e < (std::numeric_limits<Exponent>::min)())) - { - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend(); - if(e < 0) - res.negate(); - } - else - eval_ldexp(res, arg, static_cast<Exponent>(e)); -} - -/* -* Sign manipulation -*/ - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - res = arg; - res.sign() = false; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - res = arg; - res.sign() = false; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline int eval_fpclassify(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - switch(arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - return FP_ZERO; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - return FP_INFINITE; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - return FP_NAN; - } - return FP_NORMAL; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_sqrt(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - using default_ops::eval_integer_sqrt; - using default_ops::eval_bit_test; - using default_ops::eval_increment; - switch(arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - errno = EDOM; - // fallthrough... - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - res = arg; - return; - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - if(arg.sign()) - { - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - errno = EDOM; - } - else - res = arg; - return; - } - if(arg.sign()) - { - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - errno = EDOM; - return; - } - - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(arg.bits()), r, s; - eval_left_shift(t, arg.exponent() & 1 ? cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count : cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1); - eval_integer_sqrt(s, r, t); - - if(!eval_bit_test(s, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)) - { - // We have exactly the right number of cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in the result, round as required: - if(s.compare(r) < 0) - { - eval_increment(s); - } - } - typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type ae = arg.exponent(); - res.exponent() = ae / 2; - if((ae & 1) && (ae < 0)) - --res.exponent(); - copy_and_round(res, s); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_floor(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - using default_ops::eval_increment; - switch(arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - errno = EDOM; - // fallthrough... - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - res = arg; - return; - } - typedef typename mpl::if_c < sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type > ::type shift_type; - shift_type shift = - (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1; - if((arg.exponent() > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0)) - { - // Either arg is already an integer, or a special value: - res = arg; - return; - } - if(shift >= (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - { - res = static_cast<signed_limb_type>(arg.sign() ? -1 : 0); - return; - } - bool fractional = (shift_type)eval_lsb(arg.bits()) < shift; - res = arg; - eval_right_shift(res.bits(), shift); - if(fractional && res.sign()) - { - eval_increment(res.bits()); - if(eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift) - { - // Must have extended result by one bit in the increment: - --shift; - ++res.exponent(); - } - } - eval_left_shift(res.bits(), shift); -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_ceil(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - using default_ops::eval_increment; - switch(arg.exponent()) - { - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - errno = EDOM; - // fallthrough... - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero: - case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: - res = arg; - return; - } - typedef typename mpl::if_c < sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type > ::type shift_type; - shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1; - if((arg.exponent() > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0)) - { - // Either arg is already an integer, or a special value: - res = arg; - return; - } - if(shift >= (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - { - bool s = arg.sign(); // takes care of signed zeros - res = static_cast<signed_limb_type>(arg.sign() ? 0 : 1); - res.sign() = s; - return; - } - bool fractional = (shift_type)eval_lsb(arg.bits()) < shift; - res = arg; - eval_right_shift(res.bits(), shift); - if(fractional && !res.sign()) - { - eval_increment(res.bits()); - if(eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift) - { - // Must have extended result by one bit in the increment: - --shift; - ++res.exponent(); - } - } - eval_left_shift(res.bits(), shift); -} - -template<unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2> -int eval_signbit(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val) -{ - return val.sign(); -} - -template<unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2> -inline std::size_t hash_value(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val) -{ - std::size_t result = hash_value(val.bits()); - boost::hash_combine(result, val.exponent()); - boost::hash_combine(result, val.sign()); - return result; -} - - -} // namespace backends - -#ifdef BOOST_NO_SFINAE_EXPR - -namespace detail{ - -template<unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2, unsigned D2, backends::digit_base_type B2, class A2, class E2, E2 M3, E2 M4> -struct is_explicitly_convertible<backends::cpp_bin_float<D1, B1, A1, E1, M1, M2>, backends::cpp_bin_float<D2, B2, A2, E2, M3, M4> > : public mpl::true_ {}; -template<class FloatT, unsigned D2, backends::digit_base_type B2, class A2, class E2, E2 M3, E2 M4> -struct is_explicitly_convertible<FloatT, backends::cpp_bin_float<D2, B2, A2, E2, M3, M4> > : public boost::is_floating_point<FloatT> {}; - -} -#endif - -template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> -copysign BOOST_PREVENT_MACRO_SUBSTITUTION( - const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& a, - const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& b) -{ - boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> res(a); - res.backend().sign() = b.backend().sign(); - return res; -} - -using backends::cpp_bin_float; -using backends::digit_base_2; -using backends::digit_base_10; - -template<unsigned Digits, backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator> -struct number_category<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > : public boost::mpl::int_<boost::multiprecision::number_kind_floating_point>{}; - -template<unsigned Digits, backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -struct expression_template_default<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > -{ - static const expression_template_option value = is_void<Allocator>::value ? et_off : et_on; -}; - -typedef number<backends::cpp_bin_float<50> > cpp_bin_float_50; -typedef number<backends::cpp_bin_float<100> > cpp_bin_float_100; - -typedef number<backends::cpp_bin_float<24, backends::digit_base_2, void, boost::int16_t, -126, 127>, et_off> cpp_bin_float_single; -typedef number<backends::cpp_bin_float<53, backends::digit_base_2, void, boost::int16_t, -1022, 1023>, et_off> cpp_bin_float_double; -typedef number<backends::cpp_bin_float<64, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_double_extended; -typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_quad; - -} // namespace multiprecision - -namespace math { - - using boost::multiprecision::signbit; - using boost::multiprecision::copysign; - -} // namespace math - -} // namespace boost - -#include <boost/multiprecision/cpp_bin_float/io.hpp> -#include <boost/multiprecision/cpp_bin_float/transcendental.hpp> - -namespace std{ - -// -// numeric_limits [partial] specializations for the types declared in this header: -// -template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - static number_type (min)() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - typedef typename boost::mpl::front<typename number_type::backend_type::unsigned_types>::type ui_type; - value.second.backend() = ui_type(1u); - value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent; - } - return value.second; - } - static number_type (max)() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - if(boost::is_void<Allocator>::value) - eval_complement(value.second.backend().bits(), value.second.backend().bits()); - else - { - // We jump through hoops here using the backend type directly just to keep VC12 happy - // (ie compiler workaround, for very strange compiler bug): - using boost::multiprecision::default_ops::eval_add; - using boost::multiprecision::default_ops::eval_decrement; - using boost::multiprecision::default_ops::eval_left_shift; - typedef typename number_type::backend_type::rep_type int_backend_type; - typedef typename boost::mpl::front<typename int_backend_type::unsigned_types>::type ui_type; - int_backend_type i; - i = ui_type(1u); - eval_left_shift(i, boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1); - int_backend_type j(i); - eval_decrement(i); - eval_add(j, i); - value.second.backend().bits() = j; - } - value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent; - } - return value.second; - } - BOOST_STATIC_CONSTEXPR number_type lowest() - { - return -(max)(); - } - BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count; - BOOST_STATIC_CONSTEXPR int digits10 = (digits - 1) * 301 / 1000; - // Is this really correct??? - BOOST_STATIC_CONSTEXPR int max_digits10 = (digits * 301 / 1000) + 3; - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR int radix = 2; - static number_type epsilon() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - // We jump through hoops here just to keep VC12 happy (ie compiler workaround, for very strange compiler bug): - typedef typename boost::mpl::front<typename number_type::backend_type::unsigned_types>::type ui_type; - value.first = true; - value.second.backend() = ui_type(1u); - value.second = ldexp(value.second, 1 - (int)digits); - } - return value.second; - } - // What value should this be???? - static number_type round_error() - { - // returns 0.5 - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - // We jump through hoops here just to keep VC12 happy (ie compiler workaround, for very strange compiler bug): - typedef typename boost::mpl::front<typename number_type::backend_type::unsigned_types>::type ui_type; - value.second.backend() = ui_type(1u); - value.second = ldexp(value.second, -1); - } - return value.second; - } - BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent; - BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent10 = (min_exponent / 1000) * 301L; - BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent; - BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent10 = (max_exponent / 1000) * 301L; - BOOST_STATIC_CONSTEXPR bool has_infinity = true; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity; - } - return value.second; - } - static number_type quiet_NaN() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan; - } - return value.second; - } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() - { - return number_type(0); - } - BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = true; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = true; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest; -private: - struct data_initializer - { - data_initializer() - { - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::epsilon(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::round_error(); - (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::min)(); - (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::max)(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN(); - } - void do_nothing()const{} - }; - static const data_initializer initializer; -}; - -template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::initializer; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits10; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_digits10; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_signed; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_integer; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_exact; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::radix; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent10; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent10; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_infinity; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_quiet_NaN; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_signaling_NaN; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm_loss; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_iec559; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_bounded; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_modulo; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::traps; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::tinyness_before; -template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::round_style; - -#endif - -} // namespace std - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_bin_float/io.hpp b/contrib/restricted/boost/boost/multiprecision/cpp_bin_float/io.hpp deleted file mode 100644 index 8a3faaa4ff..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/cpp_bin_float/io.hpp +++ /dev/null @@ -1,700 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 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_ - -#ifndef BOOST_MP_CPP_BIN_FLOAT_IO_HPP -#define BOOST_MP_CPP_BIN_FLOAT_IO_HPP - -namespace boost{ namespace multiprecision{ namespace cpp_bf_io_detail{ - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4127) // conditional expression is constant -#endif - - -// -// Multiplies a by b and shifts the result so it fits inside max_bits bits, -// returns by how much the result was shifted. -// -template <class I> -inline I restricted_multiply(cpp_int& result, const cpp_int& a, const cpp_int& b, I max_bits, boost::int64_t& error) -{ - result = a * b; - I gb = msb(result); - I rshift = 0; - if(gb > max_bits) - { - rshift = gb - max_bits; - I lb = lsb(result); - int roundup = 0; - // The error rate increases by the error of both a and b, - // this may be overly pessimistic in many case as we're assuming - // that a and b have the same level of uncertainty... - if(lb < rshift) - error = error ? error * 2 : 1; - if(rshift) - { - BOOST_ASSERT(rshift < INT_MAX); - if(bit_test(result, static_cast<unsigned>(rshift - 1))) - { - if(lb == rshift - 1) - roundup = 1; - else - roundup = 2; - } - result >>= rshift; - } - if((roundup == 2) || ((roundup == 1) && (result.backend().limbs()[0] & 1))) - ++result; - } - return rshift; -} -// -// Computes a^e shifted to the right so it fits in max_bits, returns how far -// to the right we are shifted. -// -template <class I> -inline I restricted_pow(cpp_int& result, const cpp_int& a, I e, I max_bits, boost::int64_t& error) -{ - BOOST_ASSERT(&result != &a); - I exp = 0; - if(e == 1) - { - result = a; - return exp; - } - else if(e == 2) - { - return restricted_multiply(result, a, a, max_bits, error); - } - else if(e == 3) - { - exp = restricted_multiply(result, a, a, max_bits, error); - exp += restricted_multiply(result, result, a, max_bits, error); - return exp; - } - I p = e / 2; - exp = restricted_pow(result, a, p, max_bits, error); - exp *= 2; - exp += restricted_multiply(result, result, result, max_bits, error); - if(e & 1) - exp += restricted_multiply(result, result, a, max_bits, error); - return exp; -} - -inline int get_round_mode(const cpp_int& what, boost::int64_t location, boost::int64_t error) -{ - // - // Can we round what at /location/, if the error in what is /error/ in - // units of 0.5ulp. Return: - // - // -1: Can't round. - // 0: leave as is. - // 1: tie. - // 2: round up. - // - BOOST_ASSERT(location >= 0); - BOOST_ASSERT(location < INT_MAX); - boost::int64_t error_radius = error & 1 ? (1 + error) / 2 : error / 2; - if(error_radius && ((int)msb(error_radius) >= location)) - return -1; - if(bit_test(what, static_cast<unsigned>(location))) - { - if((int)lsb(what) == location) - return error ? -1 : 1; // Either a tie or can't round depending on whether we have any error - if(!error) - return 2; // no error, round up. - cpp_int t = what - error_radius; - if((int)lsb(t) >= location) - return -1; - return 2; - } - else if(error) - { - cpp_int t = what + error_radius; - return bit_test(t, static_cast<unsigned>(location)) ? -1 : 0; - } - return 0; -} - -inline int get_round_mode(cpp_int& r, cpp_int& d, boost::int64_t error, const cpp_int& q) -{ - // - // Lets suppose we have an inexact division by d+delta, where the true - // value for the divisor is d, and with |delta| <= error/2, then - // we have calculated q and r such that: - // - // n r - // --- = q + ----------- - // d + error d + error - // - // Rearranging for n / d we get: - // - // n delta*q + r - // --- = q + ------------- - // d d - // - // So rounding depends on whether 2r + error * q > d. - // - // We return: - // 0 = down down. - // 1 = tie. - // 2 = round up. - // -1 = couldn't decide. - // - r <<= 1; - int c = r.compare(d); - if(c == 0) - return error ? -1 : 1; - if(c > 0) - { - if(error) - { - r -= error * q; - return r.compare(d) > 0 ? 2 : -1; - } - return 2; - } - if(error) - { - r += error * q; - return r.compare(d) < 0 ? 0 : -1; - } - return 0; -} - -} // namespace - -namespace backends{ - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::operator=(const char *s) -{ - cpp_int n; - boost::intmax_t decimal_exp = 0; - boost::intmax_t digits_seen = 0; - static const boost::intmax_t max_digits_seen = 4 + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count * 301L) / 1000; - bool ss = false; - // - // Extract the sign: - // - if(*s == '-') - { - ss = true; - ++s; - } - else if(*s == '+') - ++s; - // - // Special cases first: - // - if((std::strcmp(s, "nan") == 0) || (std::strcmp(s, "NaN") == 0) || (std::strcmp(s, "NAN") == 0)) - { - return *this = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend(); - } - if((std::strcmp(s, "inf") == 0) || (std::strcmp(s, "Inf") == 0) || (std::strcmp(s, "INF") == 0) || (std::strcmp(s, "infinity") == 0) || (std::strcmp(s, "Infinity") == 0) || (std::strcmp(s, "INFINITY") == 0)) - { - *this = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend(); - if(ss) - negate(); - return *this; - } - // - // Digits before the point: - // - while(*s && (*s >= '0') && (*s <= '9')) - { - n *= 10u; - n += *s - '0'; - if(digits_seen || (*s != '0')) - ++digits_seen; - ++s; - } - // The decimal point (we really should localise this!!) - if(*s && (*s == '.')) - ++s; - // - // Digits after the point: - // - while(*s && (*s >= '0') && (*s <= '9')) - { - n *= 10u; - n += *s - '0'; - --decimal_exp; - if(digits_seen || (*s != '0')) - ++digits_seen; - ++s; - if(digits_seen > max_digits_seen) - break; - } - // - // Digits we're skipping: - // - while(*s && (*s >= '0') && (*s <= '9')) - ++s; - // - // See if there's an exponent: - // - if(*s && ((*s == 'e') || (*s == 'E'))) - { - ++s; - boost::intmax_t e = 0; - bool es = false; - if(*s && (*s == '-')) - { - es = true; - ++s; - } - else if(*s && (*s == '+')) - ++s; - while(*s && (*s >= '0') && (*s <= '9')) - { - e *= 10u; - e += *s - '0'; - ++s; - } - if(es) - e = -e; - decimal_exp += e; - } - if(*s) - { - // - // Oops unexpected input at the end of the number: - // - BOOST_THROW_EXCEPTION(std::runtime_error("Unable to parse string as a valid floating point number.")); - } - if(n == 0) - { - // Result is necessarily zero: - *this = static_cast<limb_type>(0u); - return *this; - } - - static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT; - // - // Set our working precision - this is heuristic based, we want - // a value as small as possible > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count to avoid large computations - // and excessive memory usage, but we also want to avoid having to - // up the computation and start again at a higher precision. - // So we round cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count up to the nearest whole number of limbs, and add - // one limb for good measure. This works very well for small exponents, - // but for larger exponents we may may need to restart, we could add some - // extra precision right from the start for larger exponents, but this - // seems to be slightly slower in the *average* case: - // -#ifdef BOOST_MP_STRESS_IO - boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32; -#else - boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + ((cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) ? (limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) : 0) + limb_bits; -#endif - boost::int64_t error = 0; - boost::intmax_t calc_exp = 0; - boost::intmax_t final_exponent = 0; - - if(decimal_exp >= 0) - { - // Nice and simple, the result is an integer... - do - { - cpp_int t; - if(decimal_exp) - { - calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(t, cpp_int(5), decimal_exp, max_bits, error); - calc_exp += boost::multiprecision::cpp_bf_io_detail::restricted_multiply(t, t, n, max_bits, error); - } - else - t = n; - final_exponent = (boost::int64_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 + decimal_exp + calc_exp; - int rshift = msb(t) - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1; - if(rshift > 0) - { - final_exponent += rshift; - int roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(t, rshift - 1, error); - t >>= rshift; - if((roundup == 2) || ((roundup == 1) && t.backend().limbs()[0] & 1)) - ++t; - else if(roundup < 0) - { -#ifdef BOOST_MP_STRESS_IO - max_bits += 32; -#else - max_bits *= 2; -#endif - error = 0; - continue; - } - } - else - { - BOOST_ASSERT(!error); - } - if(final_exponent > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) - { - exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent; - final_exponent -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent; - } - else if(final_exponent < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent) - { - // Underflow: - exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent; - final_exponent -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent; - } - else - { - exponent() = static_cast<Exponent>(final_exponent); - final_exponent = 0; - } - copy_and_round(*this, t.backend()); - break; - } - while(true); - - if(ss != sign()) - negate(); - } - else - { - // Result is the ratio of two integers: we need to organise the - // division so as to produce at least an N-bit result which we can - // round according to the remainder. - //cpp_int d = pow(cpp_int(5), -decimal_exp); - do - { - cpp_int d; - calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(d, cpp_int(5), -decimal_exp, max_bits, error); - int shift = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - msb(n) + msb(d); - final_exponent = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 + decimal_exp - calc_exp; - if(shift > 0) - { - n <<= shift; - final_exponent -= static_cast<Exponent>(shift); - } - cpp_int q, r; - divide_qr(n, d, q, r); - int gb = msb(q); - BOOST_ASSERT((gb >= static_cast<int>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1)); - // - // Check for rounding conditions we have to - // handle ourselves: - // - int roundup = 0; - if(gb == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1) - { - // Exactly the right number of bits, use the remainder to round: - roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(r, d, error, q); - } - else if(bit_test(q, gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) && ((int)lsb(q) == (gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))) - { - // Too many bits in q and the bits in q indicate a tie, but we can break that using r, - // note that the radius of error in r is error/2 * q: - int lshift = gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1; - q >>= lshift; - final_exponent += static_cast<Exponent>(lshift); - BOOST_ASSERT((msb(q) >= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)); - if(error && (r < (error / 2) * q)) - roundup = -1; - else if(error && (r + (error / 2) * q >= d)) - roundup = -1; - else - roundup = r ? 2 : 1; - } - else if(error && (((error / 2) * q + r >= d) || (r < (error / 2) * q))) - { - // We might have been rounding up, or got the wrong quotient: can't tell! - roundup = -1; - } - if(roundup < 0) - { -#ifdef BOOST_MP_STRESS_IO - max_bits += 32; -#else - max_bits *= 2; -#endif - error = 0; - if(shift > 0) - { - n >>= shift; - final_exponent += static_cast<Exponent>(shift); - } - continue; - } - else if((roundup == 2) || ((roundup == 1) && q.backend().limbs()[0] & 1)) - ++q; - if(final_exponent > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) - { - // Overflow: - exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent; - final_exponent -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent; - } - else if(final_exponent < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent) - { - // Underflow: - exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent; - final_exponent -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent; - } - else - { - exponent() = static_cast<Exponent>(final_exponent); - final_exponent = 0; - } - copy_and_round(*this, q.backend()); - if(ss != sign()) - negate(); - break; - } - while(true); - } - // - // Check for scaling and/or over/under-flow: - // - final_exponent += exponent(); - if(final_exponent > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) - { - // Overflow: - exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity; - bits() = limb_type(0); - } - else if(final_exponent < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent) - { - // Underflow: - exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero; - bits() = limb_type(0); - sign() = 0; - } - else - { - exponent() = static_cast<Exponent>(final_exponent); - } - return *this; -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -std::string cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::str(std::streamsize dig, std::ios_base::fmtflags f) const -{ - if(dig == 0) - dig = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::max_digits10; - - bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific; - bool fixed = !scientific && (f & std::ios_base::fixed); - - std::string s; - - if(exponent() <= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) - { - // How far to left-shift in order to demormalise the mantissa: - boost::intmax_t shift = (boost::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - (boost::intmax_t)exponent() - 1; - boost::intmax_t digits_wanted = static_cast<int>(dig); - boost::intmax_t base10_exp = exponent() >= 0 ? static_cast<boost::intmax_t>(std::floor(0.30103 * exponent())) : static_cast<boost::intmax_t>(std::ceil(0.30103 * exponent())); - // - // For fixed formatting we want /dig/ digits after the decimal point, - // so if the exponent is zero, allowing for the one digit before the - // decimal point, we want 1 + dig digits etc. - // - if(fixed) - digits_wanted += 1 + base10_exp; - if(scientific) - digits_wanted += 1; - if(digits_wanted < -1) - { - // Fixed precision, no significant digits, and nothing to round! - s = "0"; - if(sign()) - s.insert(static_cast<std::string::size_type>(0), 1, '-'); - boost::multiprecision::detail::format_float_string(s, base10_exp, dig, f, true); - return s; - } - // - // power10 is the base10 exponent we need to multiply/divide by in order - // to convert our denormalised number to an integer with the right number of digits: - // - boost::intmax_t power10 = digits_wanted - base10_exp - 1; - // - // If we calculate 5^power10 rather than 10^power10 we need to move - // 2^power10 into /shift/ - // - shift -= power10; - cpp_int i; - int roundup = 0; // 0=no rounding, 1=tie, 2=up - static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT; - // - // Set our working precision - this is heuristic based, we want - // a value as small as possible > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count to avoid large computations - // and excessive memory usage, but we also want to avoid having to - // up the computation and start again at a higher precision. - // So we round cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count up to the nearest whole number of limbs, and add - // one limb for good measure. This works very well for small exponents, - // but for larger exponents we add a few extra limbs to max_bits: - // -#ifdef BOOST_MP_STRESS_IO - boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32; -#else - boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + ((cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) ? (limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) : 0) + limb_bits; - if(power10) - max_bits += (msb(boost::multiprecision::detail::abs(power10)) / 8) * limb_bits; -#endif - do - { - boost::int64_t error = 0; - boost::intmax_t calc_exp = 0; - // - // Our integer result is: bits() * 2^-shift * 5^power10 - // - i = bits(); - if(shift < 0) - { - if(power10 >= 0) - { - // We go straight to the answer with all integer arithmetic, - // the result is always exact and never needs rounding: - BOOST_ASSERT(power10 <= (boost::intmax_t)INT_MAX); - i <<= -shift; - if(power10) - i *= pow(cpp_int(5), static_cast<unsigned>(power10)); - } - else if(power10 < 0) - { - cpp_int d; - calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(d, cpp_int(5), -power10, max_bits, error); - shift += calc_exp; - BOOST_ASSERT(shift < 0); // Must still be true! - i <<= -shift; - cpp_int r; - divide_qr(i, d, i, r); - roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(r, d, error, i); - if(roundup < 0) - { -#ifdef BOOST_MP_STRESS_IO - max_bits += 32; -#else - max_bits *= 2; -#endif - shift = (boost::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10; - continue; - } - } - } - else - { - // - // Our integer is bits() * 2^-shift * 10^power10 - // - if(power10 > 0) - { - if(power10) - { - cpp_int t; - calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(t, cpp_int(5), power10, max_bits, error); - calc_exp += boost::multiprecision::cpp_bf_io_detail::restricted_multiply(i, i, t, max_bits, error); - shift -= calc_exp; - } - if((shift < 0) || ((shift == 0) && error)) - { - // We only get here if we were asked for a crazy number of decimal digits - - // more than are present in a 2^max_bits number. -#ifdef BOOST_MP_STRESS_IO - max_bits += 32; -#else - max_bits *= 2; -#endif - shift = (boost::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10; - continue; - } - if(shift) - { - roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(i, shift - 1, error); - if(roundup < 0) - { -#ifdef BOOST_MP_STRESS_IO - max_bits += 32; -#else - max_bits *= 2; -#endif - shift = (boost::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10; - continue; - } - i >>= shift; - } - } - else - { - // We're right shifting, *and* dividing by 5^-power10, - // so 5^-power10 can never be that large or we'd simply - // get zero as a result, and that case is already handled above: - cpp_int r; - BOOST_ASSERT(-power10 < INT_MAX); - cpp_int d = pow(cpp_int(5), static_cast<unsigned>(-power10)); - d <<= shift; - divide_qr(i, d, i, r); - r <<= 1; - int c = r.compare(d); - roundup = c < 0 ? 0 : c == 0 ? 1 : 2; - } - } - s = i.str(0, std::ios_base::fmtflags(0)); - // - // Check if we got the right number of digits, this - // is really a test of whether we calculated the - // decimal exponent correctly: - // - boost::intmax_t digits_got = i ? static_cast<boost::intmax_t>(s.size()) : 0; - if(digits_got != digits_wanted) - { - base10_exp += digits_got - digits_wanted; - if(fixed) - digits_wanted = digits_got; // strange but true. - power10 = digits_wanted - base10_exp - 1; - shift = (boost::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10; - if(fixed) - break; - roundup = 0; - } - else - break; - } - while(true); - // - // Check whether we need to round up: note that we could equally round up - // the integer /i/ above, but since we need to perform the rounding *after* - // the conversion to a string and the digit count check, we might as well - // do it here: - // - if((roundup == 2) || ((roundup == 1) && ((s[s.size() - 1] - '0') & 1))) - { - boost::multiprecision::detail::round_string_up_at(s, static_cast<int>(s.size() - 1), base10_exp); - } - - if(sign()) - s.insert(static_cast<std::string::size_type>(0), 1, '-'); - - boost::multiprecision::detail::format_float_string(s, base10_exp, dig, f, false); - } - else - { - switch(exponent()) - { - case exponent_zero: - s = sign() ? "-0" : f & std::ios_base::showpos ? "+0" : "0"; - boost::multiprecision::detail::format_float_string(s, 0, dig, f, true); - break; - case exponent_nan: - s = "nan"; - break; - case exponent_infinity: - s = sign() ? "-inf" : f & std::ios_base::showpos ? "+inf" : "inf"; - break; - } - } - return s; -} - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -}}} // namespaces - -#endif - diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_bin_float/transcendental.hpp b/contrib/restricted/boost/boost/multiprecision/cpp_bin_float/transcendental.hpp deleted file mode 100644 index 5c969716a5..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/cpp_bin_float/transcendental.hpp +++ /dev/null @@ -1,148 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 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_ - -#ifndef BOOST_MULTIPRECISION_CPP_BIN_FLOAT_TRANSCENDENTAL_HPP -#define BOOST_MULTIPRECISION_CPP_BIN_FLOAT_TRANSCENDENTAL_HPP - -namespace boost{ namespace multiprecision{ namespace backends{ - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -void eval_exp_taylor(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - static const int bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count; - // - // Taylor series for small argument, note returns exp(x) - 1: - // - res = limb_type(0); - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> num(arg), denom, t; - denom = limb_type(1); - eval_add(res, num); - - for(unsigned k = 2; ; ++k) - { - eval_multiply(denom, k); - eval_multiply(num, arg); - eval_divide(t, num, denom); - eval_add(res, t); - if(eval_is_zero(t) || (res.exponent() - bits > t.exponent())) - break; - } -} - -template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -void eval_exp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) -{ - // - // This is based on MPFR's method, let: - // - // n = floor(x / ln(2)) - // - // Then: - // - // r = x - n ln(2) : 0 <= r < ln(2) - // - // We can reduce r further by dividing by 2^k, with k ~ sqrt(n), - // so if: - // - // e0 = exp(r / 2^k) - 1 - // - // With e0 evaluated by taylor series for small arguments, then: - // - // exp(x) = 2^n (1 + e0)^2^k - // - // Note that to preserve precision we actually square (1 + e0) k times, calculating - // the result less one each time, i.e. - // - // (1 + e0)^2 - 1 = e0^2 + 2e0 - // - // Then add the final 1 at the end, given that e0 is small, this effectively wipes - // out the error in the last step. - // - using default_ops::eval_multiply; - using default_ops::eval_subtract; - using default_ops::eval_add; - using default_ops::eval_convert_to; - - int type = eval_fpclassify(arg); - bool isneg = eval_get_sign(arg) < 0; - if(type == (int)FP_NAN) - { - res = arg; - errno = EDOM; - return; - } - else if(type == (int)FP_INFINITE) - { - res = arg; - if(isneg) - res = limb_type(0u); - else - res = arg; - return; - } - else if(type == (int)FP_ZERO) - { - res = limb_type(1); - return; - } - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> t, n; - if(isneg) - { - t = arg; - t.negate(); - eval_exp(res, t); - t.swap(res); - res = limb_type(1); - eval_divide(res, t); - return; - } - - eval_divide(n, arg, default_ops::get_constant_ln2<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> >()); - eval_floor(n, n); - eval_multiply(t, n, default_ops::get_constant_ln2<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> >()); - eval_subtract(t, arg); - t.negate(); - if(eval_get_sign(t) < 0) - { - // There are some very rare cases where arg/ln2 is an integer, and the subsequent multiply - // rounds up, in that situation t ends up negative at this point which breaks our invariants below: - t = limb_type(0); - } - - Exponent k, nn; - eval_convert_to(&nn, n); - - if (nn == (std::numeric_limits<Exponent>::max)()) - { - // The result will necessarily oveflow: - res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend(); - return; - } - - BOOST_ASSERT(t.compare(default_ops::get_constant_ln2<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> >()) < 0); - - k = nn ? Exponent(1) << (msb(nn) / 2) : 0; - k = (std::min)(k, (Exponent)(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count / 4)); - eval_ldexp(t, t, -k); - - eval_exp_taylor(res, t); - // - // Square 1 + res k times: - // - for(Exponent s = 0; s < k; ++s) - { - t.swap(res); - eval_multiply(res, t, t); - eval_ldexp(t, t, 1); - eval_add(res, t); - } - eval_add(res, limb_type(1)); - eval_ldexp(res, res, nn); -} - -}}} // namespaces - -#endif - diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_dec_float.hpp b/contrib/restricted/boost/boost/multiprecision/cpp_dec_float.hpp deleted file mode 100644 index 6e1509289d..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/cpp_dec_float.hpp +++ /dev/null @@ -1,3162 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2002 - 2013. -// Copyright 2011 -2013 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_0.txt) -// -// This work is based on an earlier work: -// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations", -// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469 -// -// Note that there are no "noexcept" specifications on the functions in this file: there are too many -// calls to lexical_cast (and similar) to easily analyse the code for correctness. So until compilers -// can detect noexcept misuse at compile time, the only realistic option is to simply not use it here. -// - -#ifndef BOOST_MP_CPP_DEC_FLOAT_BACKEND_HPP -#define BOOST_MP_CPP_DEC_FLOAT_BACKEND_HPP - -#include <boost/config.hpp> -#include <boost/cstdint.hpp> -#include <limits> -#ifndef BOOST_NO_CXX11_HDR_ARRAY -#include <array> -#else -#include <boost/array.hpp> -#endif -#include <boost/cstdint.hpp> -#include <boost/functional/hash_fwd.hpp> -#include <boost/multiprecision/number.hpp> -#include <boost/multiprecision/detail/big_lanczos.hpp> -#include <boost/multiprecision/detail/dynamic_array.hpp> - -// -// Headers required for Boost.Math integration: -// -#include <boost/math/policies/policy.hpp> -// -// Some includes we need from Boost.Math, since we rely on that library to provide these functions: -// -#include <boost/math/special_functions/asinh.hpp> -#include <boost/math/special_functions/acosh.hpp> -#include <boost/math/special_functions/atanh.hpp> -#include <boost/math/special_functions/cbrt.hpp> -#include <boost/math/special_functions/expm1.hpp> -#include <boost/math/special_functions/gamma.hpp> - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:6326) // comparison of two constants -#endif - -namespace boost{ -namespace multiprecision{ -namespace backends{ - -template <unsigned Digits10, class ExponentType = boost::int32_t, class Allocator = void> -class cpp_dec_float; - -} // namespace - -template <unsigned Digits10, class ExponentType, class Allocator> -struct number_category<backends::cpp_dec_float<Digits10, ExponentType, Allocator> > : public mpl::int_<number_kind_floating_point>{}; - -namespace backends{ - -template <unsigned Digits10, class ExponentType, class Allocator> -class cpp_dec_float -{ -private: - static const boost::int32_t cpp_dec_float_digits10_setting = Digits10; - - // We need at least 16-bits in the exponent type to do anything sensible: - BOOST_STATIC_ASSERT_MSG(boost::is_signed<ExponentType>::value, "ExponentType must be a signed built in integer type."); - BOOST_STATIC_ASSERT_MSG(sizeof(ExponentType) > 1, "ExponentType is too small."); - -public: - typedef mpl::list<boost::long_long_type> signed_types; - typedef mpl::list<boost::ulong_long_type> unsigned_types; - typedef mpl::list<long double> float_types; - typedef ExponentType exponent_type; - - static const boost::int32_t cpp_dec_float_radix = 10L; - static const boost::int32_t cpp_dec_float_digits10_limit_lo = 9L; - static const boost::int32_t cpp_dec_float_digits10_limit_hi = boost::integer_traits<boost::int32_t>::const_max - 100; - static const boost::int32_t cpp_dec_float_digits10 = ((cpp_dec_float_digits10_setting < cpp_dec_float_digits10_limit_lo) ? cpp_dec_float_digits10_limit_lo : ((cpp_dec_float_digits10_setting > cpp_dec_float_digits10_limit_hi) ? cpp_dec_float_digits10_limit_hi : cpp_dec_float_digits10_setting)); - static const ExponentType cpp_dec_float_max_exp10 = (static_cast<ExponentType>(1) << (std::numeric_limits<ExponentType>::digits - 5)); - static const ExponentType cpp_dec_float_min_exp10 = -cpp_dec_float_max_exp10; - static const ExponentType cpp_dec_float_max_exp = cpp_dec_float_max_exp10; - static const ExponentType cpp_dec_float_min_exp = cpp_dec_float_min_exp10; - - BOOST_STATIC_ASSERT((cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10 == -cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10)); - -private: - static const boost::int32_t cpp_dec_float_elem_digits10 = 8L; - static const boost::int32_t cpp_dec_float_elem_mask = 100000000L; - - BOOST_STATIC_ASSERT(0 == cpp_dec_float_max_exp10 % cpp_dec_float_elem_digits10); - - // There are three guard limbs. - // 1) The first limb has 'play' from 1...8 decimal digits. - // 2) The last limb also has 'play' from 1...8 decimal digits. - // 3) One limb can get lost when justifying after multiply, - // as only half of the triangle is multiplied and a carry - // from below is missing. - static const boost::int32_t cpp_dec_float_elem_number_request = static_cast<boost::int32_t>((cpp_dec_float_digits10 / cpp_dec_float_elem_digits10) + (((cpp_dec_float_digits10 % cpp_dec_float_elem_digits10) != 0) ? 1 : 0)); - - // The number of elements needed (with a minimum of two) plus three added guard limbs. - static const boost::int32_t cpp_dec_float_elem_number = static_cast<boost::int32_t>(((cpp_dec_float_elem_number_request < 2L) ? 2L : cpp_dec_float_elem_number_request) + 3L); - -public: - static const boost::int32_t cpp_dec_float_total_digits10 = static_cast<boost::int32_t>(cpp_dec_float_elem_number * cpp_dec_float_elem_digits10); - -private: - - typedef enum enum_fpclass_type - { - cpp_dec_float_finite, - cpp_dec_float_inf, - cpp_dec_float_NaN - } - fpclass_type; - -#ifndef BOOST_NO_CXX11_HDR_ARRAY - typedef typename mpl::if_<is_void<Allocator>, - std::array<boost::uint32_t, cpp_dec_float_elem_number>, - detail::dynamic_array<boost::uint32_t, cpp_dec_float_elem_number, Allocator> - >::type array_type; -#else - typedef typename mpl::if_<is_void<Allocator>, - boost::array<boost::uint32_t, cpp_dec_float_elem_number>, - detail::dynamic_array<boost::uint32_t, cpp_dec_float_elem_number, Allocator> - >::type array_type; -#endif - - array_type data; - ExponentType exp; - bool neg; - fpclass_type fpclass; - boost::int32_t prec_elem; - - // - // Special values constructor: - // - cpp_dec_float(fpclass_type c) : - data(), - exp (static_cast<ExponentType>(0)), - neg (false), - fpclass (c), - prec_elem(cpp_dec_float_elem_number) { } - - // - // Static data initializer: - // - struct initializer - { - initializer() - { - cpp_dec_float<Digits10, ExponentType, Allocator>::nan(); - cpp_dec_float<Digits10, ExponentType, Allocator>::inf(); - (cpp_dec_float<Digits10, ExponentType, Allocator>::min)(); - (cpp_dec_float<Digits10, ExponentType, Allocator>::max)(); - cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); - cpp_dec_float<Digits10, ExponentType, Allocator>::one(); - cpp_dec_float<Digits10, ExponentType, Allocator>::two(); - cpp_dec_float<Digits10, ExponentType, Allocator>::half(); - cpp_dec_float<Digits10, ExponentType, Allocator>::double_min(); - cpp_dec_float<Digits10, ExponentType, Allocator>::double_max(); - cpp_dec_float<Digits10, ExponentType, Allocator>::long_double_max(); - cpp_dec_float<Digits10, ExponentType, Allocator>::long_double_min(); - cpp_dec_float<Digits10, ExponentType, Allocator>::long_long_max(); - cpp_dec_float<Digits10, ExponentType, Allocator>::long_long_min(); - cpp_dec_float<Digits10, ExponentType, Allocator>::ulong_long_max(); - cpp_dec_float<Digits10, ExponentType, Allocator>::eps(); - cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(0); - } - void do_nothing(){} - }; - - static initializer init; - -public: - // Constructors - cpp_dec_float() BOOST_MP_NOEXCEPT_IF(noexcept(array_type())) : - data(), - exp (static_cast<ExponentType>(0)), - neg (false), - fpclass (cpp_dec_float_finite), - prec_elem(cpp_dec_float_elem_number) { } - - cpp_dec_float(const char* s) : - data(), - exp (static_cast<ExponentType>(0)), - neg (false), - fpclass (cpp_dec_float_finite), - prec_elem(cpp_dec_float_elem_number) - { - *this = s; - } - - template<class I> - cpp_dec_float(I i, typename enable_if<is_unsigned<I> >::type* = 0) : - data(), - exp (static_cast<ExponentType>(0)), - neg (false), - fpclass (cpp_dec_float_finite), - prec_elem(cpp_dec_float_elem_number) - { - from_unsigned_long_long(i); - } - - template <class I> - cpp_dec_float(I i, typename enable_if<is_signed<I> >::type* = 0) : - data(), - exp (static_cast<ExponentType>(0)), - neg (false), - fpclass (cpp_dec_float_finite), - prec_elem(cpp_dec_float_elem_number) - { - if(i < 0) - { - from_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(i)); - negate(); - } - else - from_unsigned_long_long(i); - } - - cpp_dec_float(const cpp_dec_float& f) BOOST_MP_NOEXCEPT_IF(noexcept(array_type(std::declval<const array_type&>()))) : - data (f.data), - exp (f.exp), - neg (f.neg), - fpclass (f.fpclass), - prec_elem(f.prec_elem) { } - - template <unsigned D, class ET, class A> - cpp_dec_float(const cpp_dec_float<D, ET, A>& f, typename enable_if_c<D <= Digits10>::type* = 0) : - data(), - exp (f.exp), - neg (f.neg), - fpclass (static_cast<fpclass_type>(static_cast<int>(f.fpclass))), - prec_elem(cpp_dec_float_elem_number) - { - std::copy(f.data.begin(), f.data.begin() + f.prec_elem, data.begin()); - } - template <unsigned D, class ET, class A> - explicit cpp_dec_float(const cpp_dec_float<D, ET, A>& f, typename disable_if_c<D <= Digits10>::type* = 0) : - data(), - exp (f.exp), - neg (f.neg), - fpclass (static_cast<fpclass_type>(static_cast<int>(f.fpclass))), - prec_elem(cpp_dec_float_elem_number) - { - // TODO: this doesn't round! - std::copy(f.data.begin(), f.data.begin() + prec_elem, data.begin()); - } - - template <class F> - cpp_dec_float(const F val, typename enable_if_c<is_floating_point<F>::value -#ifdef BOOST_HAS_FLOAT128 - && !boost::is_same<F, __float128>::value -#endif - >::type* = 0) : - data(), - exp (static_cast<ExponentType>(0)), - neg (false), - fpclass (cpp_dec_float_finite), - prec_elem(cpp_dec_float_elem_number) - { - *this = val; - } - - cpp_dec_float(const double mantissa, const ExponentType exponent); - - std::size_t hash()const - { - std::size_t result = 0; - for(int i = 0; i < prec_elem; ++i) - boost::hash_combine(result, data[i]); - boost::hash_combine(result, exp); - boost::hash_combine(result, neg); - boost::hash_combine(result, fpclass); - return result; - } - - // Specific special values. - static const cpp_dec_float& nan() - { - static const cpp_dec_float val(cpp_dec_float_NaN); - init.do_nothing(); - return val; - } - - static const cpp_dec_float& inf() - { - static const cpp_dec_float val(cpp_dec_float_inf); - init.do_nothing(); - return val; - } - - static const cpp_dec_float& (max)() - { - init.do_nothing(); - static cpp_dec_float val_max = std::string("1.0e" + boost::lexical_cast<std::string>(cpp_dec_float_max_exp10)).c_str(); - return val_max; - } - - static const cpp_dec_float& (min)() - { - init.do_nothing(); - static cpp_dec_float val_min = std::string("1.0e" + boost::lexical_cast<std::string>(cpp_dec_float_min_exp10)).c_str(); - return val_min; - } - - static const cpp_dec_float& zero() - { - init.do_nothing(); - static cpp_dec_float val(static_cast<boost::ulong_long_type>(0u)); - return val; - } - - static const cpp_dec_float& one() - { - init.do_nothing(); - static cpp_dec_float val(static_cast<boost::ulong_long_type>(1u)); - return val; - } - - static const cpp_dec_float& two() - { - init.do_nothing(); - static cpp_dec_float val(static_cast<boost::ulong_long_type>(2u)); - return val; - } - - static const cpp_dec_float& half() - { - init.do_nothing(); - static cpp_dec_float val(0.5L); - return val; - } - - static const cpp_dec_float& double_min() - { - init.do_nothing(); - static cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::min)())); - return val; - } - - static const cpp_dec_float& double_max() - { - init.do_nothing(); - static cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::max)())); - return val; - } - - static const cpp_dec_float& long_double_min() - { - init.do_nothing(); -#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - static cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::min)())); -#else - static cpp_dec_float val((std::numeric_limits<long double>::min)()); -#endif - return val; - } - - static const cpp_dec_float& long_double_max() - { - init.do_nothing(); -#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - static cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::max)())); -#else - static cpp_dec_float val((std::numeric_limits<long double>::max)()); -#endif - return val; - } - - static const cpp_dec_float& long_long_max() - { - init.do_nothing(); - static cpp_dec_float val((std::numeric_limits<boost::long_long_type>::max)()); - return val; - } - - static const cpp_dec_float& long_long_min() - { - init.do_nothing(); - static cpp_dec_float val((std::numeric_limits<boost::long_long_type>::min)()); - return val; - } - - static const cpp_dec_float& ulong_long_max() - { - init.do_nothing(); - static cpp_dec_float val((std::numeric_limits<boost::ulong_long_type>::max)()); - return val; - } - - static const cpp_dec_float& eps() - { - init.do_nothing(); - static cpp_dec_float val(1.0, 1 - static_cast<int>(cpp_dec_float_digits10)); - return val; - } - - // Basic operations. - cpp_dec_float& operator=(const cpp_dec_float& v) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<array_type&>() = std::declval<const array_type&>())) - { - data = v.data; - exp = v.exp; - neg = v.neg; - fpclass = v.fpclass; - prec_elem = v.prec_elem; - return *this; - } - - template <unsigned D> - cpp_dec_float& operator=(const cpp_dec_float<D>& f) - { - exp = f.exp; - neg = f.neg; - fpclass = static_cast<enum_fpclass_type>(static_cast<int>(f.fpclass)); - unsigned elems = (std::min)(f.prec_elem, cpp_dec_float_elem_number); - std::copy(f.data.begin(), f.data.begin() + elems, data.begin()); - std::fill(data.begin() + elems, data.end(), 0); - prec_elem = cpp_dec_float_elem_number; - return *this; - } - - cpp_dec_float& operator=(boost::long_long_type v) - { - if(v < 0) - { - from_unsigned_long_long(-v); - negate(); - } - else - from_unsigned_long_long(v); - return *this; - } - - cpp_dec_float& operator=(boost::ulong_long_type v) - { - from_unsigned_long_long(v); - return *this; - } - - cpp_dec_float& operator=(long double v); - - cpp_dec_float& operator=(const char* v) - { - rd_string(v); - return *this; - } - - cpp_dec_float& operator+=(const cpp_dec_float& v); - cpp_dec_float& operator-=(const cpp_dec_float& v); - cpp_dec_float& operator*=(const cpp_dec_float& v); - cpp_dec_float& operator/=(const cpp_dec_float& v); - - cpp_dec_float& add_unsigned_long_long(const boost::ulong_long_type n) - { - cpp_dec_float t; - t.from_unsigned_long_long(n); - return *this += t; - } - - cpp_dec_float& sub_unsigned_long_long(const boost::ulong_long_type n) - { - cpp_dec_float t; - t.from_unsigned_long_long(n); - return *this -= t; - } - - cpp_dec_float& mul_unsigned_long_long(const boost::ulong_long_type n); - cpp_dec_float& div_unsigned_long_long(const boost::ulong_long_type n); - - // Elementary primitives. - cpp_dec_float& calculate_inv (); - cpp_dec_float& calculate_sqrt(); - - void negate() - { - if(!iszero()) - neg = !neg; - } - - // Comparison functions - bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_NaN); } - bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_inf); } - bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_finite); } - - bool iszero () const - { - return ((fpclass == cpp_dec_float_finite) && (data[0u] == 0u)); - } - - bool isone () const; - bool isint () const; - bool isneg () const { return neg; } - - // Operators pre-increment and pre-decrement - cpp_dec_float& operator++() - { - return *this += one(); - } - - cpp_dec_float& operator--() - { - return *this -= one(); - } - - std::string str(boost::intmax_t digits, std::ios_base::fmtflags f)const; - - int compare(const cpp_dec_float& v)const; - - template <class V> - int compare(const V& v)const - { - cpp_dec_float<Digits10, ExponentType, Allocator> t; - t = v; - return compare(t); - } - - void swap(cpp_dec_float& v) - { - data.swap(v.data); - std::swap(exp, v.exp); - std::swap(neg, v.neg); - std::swap(fpclass, v.fpclass); - std::swap(prec_elem, v.prec_elem); - } - - double extract_double() const; - long double extract_long_double() const; - boost::long_long_type extract_signed_long_long() const; - boost::ulong_long_type extract_unsigned_long_long() const; - void extract_parts(double& mantissa, ExponentType& exponent) const; - cpp_dec_float extract_integer_part() const; - - void precision(const boost::int32_t prec_digits) - { - if(prec_digits >= cpp_dec_float_total_digits10) - { - prec_elem = cpp_dec_float_elem_number; - } - else - { - const boost::int32_t elems = static_cast<boost::int32_t>( static_cast<boost::int32_t>( (prec_digits + (cpp_dec_float_elem_digits10 / 2)) / cpp_dec_float_elem_digits10) - + static_cast<boost::int32_t>(((prec_digits % cpp_dec_float_elem_digits10) != 0) ? 1 : 0)); - - prec_elem = (std::min)(cpp_dec_float_elem_number, (std::max)(elems, static_cast<boost::int32_t>(2))); - } - } - static cpp_dec_float pow2(boost::long_long_type i); - ExponentType order()const - { - const bool bo_order_is_zero = ((!(isfinite)()) || (data[0] == static_cast<boost::uint32_t>(0u))); - // - // Binary search to find the order of the leading term: - // - ExponentType prefix = 0; - - if(data[0] >= 100000UL) - { - if(data[0] >= 10000000UL) - { - if(data[0] >= 100000000UL) - { - if(data[0] >= 1000000000UL) - prefix = 9; - else - prefix = 8; - } - else - prefix = 7; - } - else - { - if(data[0] >= 1000000UL) - prefix = 6; - else - prefix = 5; - } - } - else - { - if(data[0] >= 1000UL) - { - if(data[0] >= 10000UL) - prefix = 4; - else - prefix = 3; - } - else - { - if(data[0] >= 100) - prefix = 2; - else if(data[0] >= 10) - prefix = 1; - } - } - - return (bo_order_is_zero ? static_cast<ExponentType>(0) : static_cast<ExponentType>(exp + prefix)); - } - - template<class Archive> - void serialize(Archive & ar, const unsigned int /*version*/) - { - for(unsigned i = 0; i < data.size(); ++i) - ar & data[i]; - ar & exp; - ar & neg; - ar & fpclass; - ar & prec_elem; - } - -private: - static bool data_elem_is_non_zero_predicate(const boost::uint32_t& d) { return (d != static_cast<boost::uint32_t>(0u)); } - static bool data_elem_is_non_nine_predicate(const boost::uint32_t& d) { return (d != static_cast<boost::uint32_t>(cpp_dec_float::cpp_dec_float_elem_mask - 1)); } - static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast<char>('0')); } - - void from_unsigned_long_long(const boost::ulong_long_type u); - - int cmp_data(const array_type& vd) const; - - - static boost::uint32_t mul_loop_uv(boost::uint32_t* const u, const boost::uint32_t* const v, const boost::int32_t p); - static boost::uint32_t mul_loop_n (boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p); - static boost::uint32_t div_loop_n (boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p); - - bool rd_string(const char* const s); - - template <unsigned D, class ET, class A> - friend class cpp_dec_float; -}; - -template <unsigned Digits10, class ExponentType, class Allocator> -typename cpp_dec_float<Digits10, ExponentType, Allocator>::initializer cpp_dec_float<Digits10, ExponentType, Allocator>::init; - -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_radix; -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10_setting; -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10_limit_lo; -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10_limit_hi; -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10; -template <unsigned Digits10, class ExponentType, class Allocator> -const ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp; -template <unsigned Digits10, class ExponentType, class Allocator> -const ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp; -template <unsigned Digits10, class ExponentType, class Allocator> -const ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10; -template <unsigned Digits10, class ExponentType, class Allocator> -const ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10; -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_digits10; -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_number_request; -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_number; -template <unsigned Digits10, class ExponentType, class Allocator> -const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_mask; - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator+=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v) -{ - if((isnan)()) - { - return *this; - } - - if((isinf)()) - { - if((v.isinf)() && (isneg() != v.isneg())) - { - *this = nan(); - } - return *this; - } - - if(iszero()) - { - return operator=(v); - } - - if((v.isnan)() || (v.isinf)()) - { - *this = v; - return *this; - } - - // Get the offset for the add/sub operation. - static const ExponentType max_delta_exp = static_cast<ExponentType>((cpp_dec_float_elem_number - 1) * cpp_dec_float_elem_digits10); - - const ExponentType ofs_exp = static_cast<ExponentType>(exp - v.exp); - - // Check if the operation is out of range, requiring special handling. - if(v.iszero() || (ofs_exp > max_delta_exp)) - { - // Result is *this unchanged since v is negligible compared to *this. - return *this; - } - else if(ofs_exp < -max_delta_exp) - { - // Result is *this = v since *this is negligible compared to v. - return operator=(v); - } - - // Do the add/sub operation. - - typename array_type::iterator p_u = data.begin(); - typename array_type::const_iterator p_v = v.data.begin(); - bool b_copy = false; - const boost::int32_t ofs = static_cast<boost::int32_t>(static_cast<boost::int32_t>(ofs_exp) / cpp_dec_float_elem_digits10); - array_type n_data; - - if(neg == v.neg) - { - // Add v to *this, where the data array of either *this or v - // might have to be treated with a positive, negative or zero offset. - // The result is stored in *this. The data are added one element - // at a time, each element with carry. - if(ofs >= static_cast<boost::int32_t>(0)) - { - std::copy(v.data.begin(), v.data.end() - static_cast<size_t>(ofs), n_data.begin() + static_cast<size_t>(ofs)); - std::fill(n_data.begin(), n_data.begin() + static_cast<size_t>(ofs), static_cast<boost::uint32_t>(0u)); - p_v = n_data.begin(); - } - else - { - std::copy(data.begin(), data.end() - static_cast<size_t>(-ofs), n_data.begin() + static_cast<size_t>(-ofs)); - std::fill(n_data.begin(), n_data.begin() + static_cast<size_t>(-ofs), static_cast<boost::uint32_t>(0u)); - p_u = n_data.begin(); - b_copy = true; - } - - // Addition algorithm - boost::uint32_t carry = static_cast<boost::uint32_t>(0u); - - for(boost::int32_t j = static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1)); j >= static_cast<boost::int32_t>(0); j--) - { - boost::uint32_t t = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(p_u[j] + p_v[j]) + carry); - carry = t / static_cast<boost::uint32_t>(cpp_dec_float_elem_mask); - p_u[j] = static_cast<boost::uint32_t>(t - static_cast<boost::uint32_t>(carry * static_cast<boost::uint32_t>(cpp_dec_float_elem_mask))); - } - - if(b_copy) - { - data = n_data; - exp = v.exp; - } - - // There needs to be a carry into the element -1 of the array data - if(carry != static_cast<boost::uint32_t>(0u)) - { - std::copy_backward(data.begin(), data.end() - static_cast<std::size_t>(1u), data.end()); - data[0] = carry; - exp += static_cast<ExponentType>(cpp_dec_float_elem_digits10); - } - } - else - { - // Subtract v from *this, where the data array of either *this or v - // might have to be treated with a positive, negative or zero offset. - if((ofs > static_cast<boost::int32_t>(0)) - || ( (ofs == static_cast<boost::int32_t>(0)) - && (cmp_data(v.data) > static_cast<boost::int32_t>(0))) - ) - { - // In this case, |u| > |v| and ofs is positive. - // Copy the data of v, shifted down to a lower value - // into the data array m_n. Set the operand pointer p_v - // to point to the copied, shifted data m_n. - std::copy(v.data.begin(), v.data.end() - static_cast<size_t>(ofs), n_data.begin() + static_cast<size_t>(ofs)); - std::fill(n_data.begin(), n_data.begin() + static_cast<size_t>(ofs), static_cast<boost::uint32_t>(0u)); - p_v = n_data.begin(); - } - else - { - if(ofs != static_cast<boost::int32_t>(0)) - { - // In this case, |u| < |v| and ofs is negative. - // Shift the data of u down to a lower value. - std::copy_backward(data.begin(), data.end() - static_cast<size_t>(-ofs), data.end()); - std::fill(data.begin(), data.begin() + static_cast<size_t>(-ofs), static_cast<boost::uint32_t>(0u)); - } - - // Copy the data of v into the data array n_data. - // Set the u-pointer p_u to point to m_n and the - // operand pointer p_v to point to the shifted - // data m_data. - n_data = v.data; - p_u = n_data.begin(); - p_v = data.begin(); - b_copy = true; - } - - boost::int32_t j; - - // Subtraction algorithm - boost::int32_t borrow = static_cast<boost::int32_t>(0); - - for(j = static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1)); j >= static_cast<boost::int32_t>(0); j--) - { - boost::int32_t t = static_cast<boost::int32_t>(static_cast<boost::int32_t>( static_cast<boost::int32_t>(p_u[j]) - - static_cast<boost::int32_t>(p_v[j])) - borrow); - - // Underflow? Borrow? - if(t < static_cast<boost::int32_t>(0)) - { - // Yes, underflow and borrow - t += static_cast<boost::int32_t>(cpp_dec_float_elem_mask); - borrow = static_cast<boost::int32_t>(1); - } - else - { - borrow = static_cast<boost::int32_t>(0); - } - - p_u[j] = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(t) % static_cast<boost::uint32_t>(cpp_dec_float_elem_mask)); - } - - if(b_copy) - { - data = n_data; - exp = v.exp; - neg = v.neg; - } - - // Is it necessary to justify the data? - const typename array_type::const_iterator first_nonzero_elem = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate); - - if(first_nonzero_elem != data.begin()) - { - if(first_nonzero_elem == data.end()) - { - // This result of the subtraction is exactly zero. - // Reset the sign and the exponent. - neg = false; - exp = static_cast<ExponentType>(0); - } - else - { - // Justify the data - const std::size_t sj = static_cast<std::size_t>(std::distance<typename array_type::const_iterator>(data.begin(), first_nonzero_elem)); - - std::copy(data.begin() + static_cast<std::size_t>(sj), data.end(), data.begin()); - std::fill(data.end() - sj, data.end(), static_cast<boost::uint32_t>(0u)); - - exp -= static_cast<ExponentType>(sj * static_cast<std::size_t>(cpp_dec_float_elem_digits10)); - } - } - } - - // Handle underflow. - if(iszero()) - return (*this = zero()); - - // Check for potential overflow. - const bool b_result_might_overflow = (exp >= static_cast<ExponentType>(cpp_dec_float_max_exp10)); - - // Handle overflow. - if(b_result_might_overflow) - { - const bool b_result_is_neg = neg; - neg = false; - - if(compare((cpp_dec_float::max)()) > 0) - *this = inf(); - - neg = b_result_is_neg; - } - - return *this; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator-=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v) -{ - // Use *this - v = -(-*this + v). - negate(); - *this += v; - negate(); - return *this; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator*=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v) -{ - // Evaluate the sign of the result. - const bool b_result_is_neg = (neg != v.neg); - - // Artificially set the sign of the result to be positive. - neg = false; - - // Handle special cases like zero, inf and NaN. - const bool b_u_is_inf = (isinf)(); - const bool b_v_is_inf = (v.isinf)(); - const bool b_u_is_zero = iszero(); - const bool b_v_is_zero = v.iszero(); - - if( ((isnan)() || (v.isnan)()) - || (b_u_is_inf && b_v_is_zero) - || (b_v_is_inf && b_u_is_zero) - ) - { - *this = nan(); - return *this; - } - - if(b_u_is_inf || b_v_is_inf) - { - *this = inf(); - if(b_result_is_neg) - negate(); - return *this; - } - - if(b_u_is_zero || b_v_is_zero) - { - return *this = zero(); - } - - // Check for potential overflow or underflow. - const bool b_result_might_overflow = ((exp + v.exp) >= static_cast<ExponentType>(cpp_dec_float_max_exp10)); - const bool b_result_might_underflow = ((exp + v.exp) <= static_cast<ExponentType>(cpp_dec_float_min_exp10)); - - // Set the exponent of the result. - exp += v.exp; - - const boost::int32_t prec_mul = (std::min)(prec_elem, v.prec_elem); - - const boost::uint32_t carry = mul_loop_uv(data.data(), v.data.data(), prec_mul); - - // Handle a potential carry. - if(carry != static_cast<boost::uint32_t>(0u)) - { - exp += cpp_dec_float_elem_digits10; - - // Shift the result of the multiplication one element to the right... - std::copy_backward(data.begin(), - data.begin() + static_cast<std::size_t>(prec_elem - static_cast<boost::int32_t>(1)), - data.begin() + static_cast<std::size_t>(prec_elem)); - - // ... And insert the carry. - data.front() = carry; - } - - // Handle overflow. - if(b_result_might_overflow && (compare((cpp_dec_float::max)()) > 0)) - { - *this = inf(); - } - - // Handle underflow. - if(b_result_might_underflow && (compare((cpp_dec_float::min)()) < 0)) - { - *this = zero(); - - return *this; - } - - // Set the sign of the result. - neg = b_result_is_neg; - - return *this; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator/=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v) -{ - if(iszero()) - { - if((v.isnan)()) - { - return *this = v; - } - else if(v.iszero()) - { - return *this = nan(); - } - } - - const bool u_and_v_are_finite_and_identical = ( (isfinite)() - && (fpclass == v.fpclass) - && (exp == v.exp) - && (cmp_data(v.data) == static_cast<boost::int32_t>(0))); - - if(u_and_v_are_finite_and_identical) - { - if(neg != v.neg) - { - *this = one(); - negate(); - } - else - *this = one(); - return *this; - } - else - { - cpp_dec_float t(v); - t.calculate_inv(); - return operator*=(t); - } -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::mul_unsigned_long_long(const boost::ulong_long_type n) -{ - // Multiply *this with a constant boost::ulong_long_type. - - // Evaluate the sign of the result. - const bool b_neg = neg; - - // Artificially set the sign of the result to be positive. - neg = false; - - // Handle special cases like zero, inf and NaN. - const bool b_u_is_inf = (isinf)(); - const bool b_n_is_zero = (n == static_cast<boost::int32_t>(0)); - - if((isnan)() || (b_u_is_inf && b_n_is_zero)) - { - return (*this = nan()); - } - - if(b_u_is_inf) - { - *this = inf(); - if(b_neg) - negate(); - return *this; - } - - if(iszero() || b_n_is_zero) - { - // Multiplication by zero. - return *this = zero(); - } - - if(n >= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask)) - { - neg = b_neg; - cpp_dec_float t; - t = n; - return operator*=(t); - } - - if(n == static_cast<boost::ulong_long_type>(1u)) - { - neg = b_neg; - return *this; - } - - // Set up the multiplication loop. - const boost::uint32_t nn = static_cast<boost::uint32_t>(n); - const boost::uint32_t carry = mul_loop_n(data.data(), nn, prec_elem); - - // Handle the carry and adjust the exponent. - if(carry != static_cast<boost::uint32_t>(0u)) - { - exp += static_cast<ExponentType>(cpp_dec_float_elem_digits10); - - // Shift the result of the multiplication one element to the right. - std::copy_backward(data.begin(), - data.begin() + static_cast<std::size_t>(prec_elem - static_cast<boost::int32_t>(1)), - data.begin() + static_cast<std::size_t>(prec_elem)); - - data.front() = static_cast<boost::uint32_t>(carry); - } - - // Check for potential overflow. - const bool b_result_might_overflow = (exp >= cpp_dec_float_max_exp10); - - // Handle overflow. - if(b_result_might_overflow && (compare((cpp_dec_float::max)()) > 0)) - { - *this = inf(); - } - - // Set the sign. - neg = b_neg; - - return *this; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::div_unsigned_long_long(const boost::ulong_long_type n) -{ - // Divide *this by a constant boost::ulong_long_type. - - // Evaluate the sign of the result. - const bool b_neg = neg; - - // Artificially set the sign of the result to be positive. - neg = false; - - // Handle special cases like zero, inf and NaN. - if((isnan)()) - { - return *this; - } - - if((isinf)()) - { - *this = inf(); - if(b_neg) - negate(); - return *this; - } - - if(n == static_cast<boost::ulong_long_type>(0u)) - { - // Divide by 0. - if(iszero()) - { - *this = nan(); - return *this; - } - else - { - *this = inf(); - if(isneg()) - negate(); - return *this; - } - } - - if(iszero()) - { - return *this; - } - - if(n >= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask)) - { - neg = b_neg; - cpp_dec_float t; - t = n; - return operator/=(t); - } - - const boost::uint32_t nn = static_cast<boost::uint32_t>(n); - - if(nn > static_cast<boost::uint32_t>(1u)) - { - // Do the division loop. - const boost::uint32_t prev = div_loop_n(data.data(), nn, prec_elem); - - // Determine if one leading zero is in the result data. - if(data[0] == static_cast<boost::uint32_t>(0u)) - { - // Adjust the exponent - exp -= static_cast<ExponentType>(cpp_dec_float_elem_digits10); - - // Shift result of the division one element to the left. - std::copy(data.begin() + static_cast<std::size_t>(1u), - data.begin() + static_cast<std::size_t>(prec_elem - static_cast<boost::int32_t>(1)), - data.begin()); - - data[prec_elem - static_cast<boost::int32_t>(1)] = static_cast<boost::uint32_t>(static_cast<boost::uint64_t>(prev * static_cast<boost::uint64_t>(cpp_dec_float_elem_mask)) / nn); - } - } - - // Check for potential underflow. - const bool b_result_might_underflow = (exp <= cpp_dec_float_min_exp10); - - // Handle underflow. - if(b_result_might_underflow && (compare((cpp_dec_float::min)()) < 0)) - return (*this = zero()); - - // Set the sign of the result. - neg = b_neg; - - return *this; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::calculate_inv() -{ - // Compute the inverse of *this. - const bool b_neg = neg; - - neg = false; - - // Handle special cases like zero, inf and NaN. - if(iszero()) - { - *this = inf(); - if(b_neg) - negate(); - return *this; - } - - if((isnan)()) - { - return *this; - } - - if((isinf)()) - { - return *this = zero(); - } - - if(isone()) - { - if(b_neg) - negate(); - return *this; - } - - // Save the original *this. - cpp_dec_float<Digits10, ExponentType, Allocator> x(*this); - - // Generate the initial estimate using division. - // Extract the mantissa and exponent for a "manual" - // computation of the estimate. - double dd; - ExponentType ne; - x.extract_parts(dd, ne); - - // Do the inverse estimate using double precision estimates of mantissa and exponent. - operator=(cpp_dec_float<Digits10, ExponentType, Allocator>(1.0 / dd, -ne)); - - // Compute the inverse of *this. Quadratically convergent Newton-Raphson iteration - // is used. During the iterative steps, the precision of the calculation is limited - // to the minimum required in order to minimize the run-time. - - static const boost::int32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3; - - for(boost::int32_t digits = double_digits10_minus_a_few; digits <= cpp_dec_float_total_digits10; digits *= static_cast<boost::int32_t>(2)) - { - // Adjust precision of the terms. - precision(static_cast<boost::int32_t>((digits + 10) * static_cast<boost::int32_t>(2))); - x.precision(static_cast<boost::int32_t>((digits + 10) * static_cast<boost::int32_t>(2))); - - // Next iteration. - cpp_dec_float t(*this); - t *= x; - t -= two(); - t.negate(); - *this *= t; - } - - neg = b_neg; - - prec_elem = cpp_dec_float_elem_number; - - return *this; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::calculate_sqrt() -{ - // Compute the square root of *this. - - if((isinf)() && !isneg()) - { - return *this; - } - - if(isneg() || (!(isfinite)())) - { - *this = nan(); - errno = EDOM; - return *this; - } - - if(iszero() || isone()) - { - return *this; - } - - // Save the original *this. - cpp_dec_float<Digits10, ExponentType, Allocator> x(*this); - - // Generate the initial estimate using division. - // Extract the mantissa and exponent for a "manual" - // computation of the estimate. - double dd; - ExponentType ne; - extract_parts(dd, ne); - - // Force the exponent to be an even multiple of two. - if((ne % static_cast<ExponentType>(2)) != static_cast<ExponentType>(0)) - { - ++ne; - dd /= 10.0; - } - - // Setup the iteration. - // Estimate the square root using simple manipulations. - const double sqd = std::sqrt(dd); - - *this = cpp_dec_float<Digits10, ExponentType, Allocator>(sqd, static_cast<ExponentType>(ne / static_cast<ExponentType>(2))); - - // Estimate 1.0 / (2.0 * x0) using simple manipulations. - cpp_dec_float<Digits10, ExponentType, Allocator> vi(0.5 / sqd, static_cast<ExponentType>(-ne / static_cast<ExponentType>(2))); - - // Compute the square root of x. Coupled Newton iteration - // as described in "Pi Unleashed" is used. During the - // iterative steps, the precision of the calculation is - // limited to the minimum required in order to minimize - // the run-time. - // - // Book references: - // http://www.jjj.de/pibook/pibook.html - // http://www.amazon.com/exec/obidos/tg/detail/-/3540665722/qid=1035535482/sr=8-7/ref=sr_8_7/104-3357872-6059916?v=glance&n=507846 - - static const boost::uint32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3; - - for(boost::int32_t digits = double_digits10_minus_a_few; digits <= cpp_dec_float_total_digits10; digits *= 2u) - { - // Adjust precision of the terms. - precision((digits + 10) * 2); - vi.precision((digits + 10) * 2); - - // Next iteration of vi - cpp_dec_float t(*this); - t *= vi; - t.negate(); - t.mul_unsigned_long_long(2u); - t += one(); - t *= vi; - vi += t; - - // Next iteration of *this - t = *this; - t *= *this; - t.negate(); - t += x; - t *= vi; - *this += t; - } - - prec_elem = cpp_dec_float_elem_number; - - return *this; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -int cpp_dec_float<Digits10, ExponentType, Allocator>::cmp_data(const array_type& vd) const -{ - // Compare the data of *this with those of v. - // Return +1 for *this > v - // 0 for *this = v - // -1 for *this < v - - const std::pair<typename array_type::const_iterator, typename array_type::const_iterator> mismatch_pair = std::mismatch(data.begin(), data.end(), vd.begin()); - - const bool is_equal = ((mismatch_pair.first == data.end()) && (mismatch_pair.second == vd.end())); - - if(is_equal) - { - return 0; - } - else - { - return ((*mismatch_pair.first > *mismatch_pair.second) ? 1 : -1); - } -} - -template <unsigned Digits10, class ExponentType, class Allocator> -int cpp_dec_float<Digits10, ExponentType, Allocator>::compare(const cpp_dec_float& v) const -{ - // Compare v with *this. - // Return +1 for *this > v - // 0 for *this = v - // -1 for *this < v - - // Handle all non-finite cases. - if((!(isfinite)()) || (!(v.isfinite)())) - { - // NaN can never equal NaN. Return an implementation-dependent - // signed result. Also note that comparison of NaN with NaN - // using operators greater-than or less-than is undefined. - if((isnan)() || (v.isnan)()) { return ((isnan)() ? 1 : -1); } - - if((isinf)() && (v.isinf)()) - { - // Both *this and v are infinite. They are equal if they have the same sign. - // Otherwise, *this is less than v if and only if *this is negative. - return ((neg == v.neg) ? 0 : (neg ? -1 : 1)); - } - - if((isinf)()) - { - // *this is infinite, but v is finite. - // So negative infinite *this is less than any finite v. - // Whereas positive infinite *this is greater than any finite v. - return (isneg() ? -1 : 1); - } - else - { - // *this is finite, and v is infinite. - // So any finite *this is greater than negative infinite v. - // Whereas any finite *this is less than positive infinite v. - return (v.neg ? 1 : -1); - } - } - - // And now handle all *finite* cases. - if(iszero()) - { - // The value of *this is zero and v is either zero or non-zero. - return (v.iszero() ? 0 - : (v.neg ? 1 : -1)); - } - else if(v.iszero()) - { - // The value of v is zero and *this is non-zero. - return (neg ? -1 : 1); - } - else - { - // Both *this and v are non-zero. - - if(neg != v.neg) - { - // The signs are different. - return (neg ? -1 : 1); - } - else if(exp != v.exp) - { - // The signs are the same and the exponents are different. - const int val_cexpression = ((exp < v.exp) ? 1 : -1); - - return (neg ? val_cexpression : -val_cexpression); - } - else - { - // The signs are the same and the exponents are the same. - // Compare the data. - const int val_cmp_data = cmp_data(v.data); - - return ((!neg) ? val_cmp_data : -val_cmp_data); - } - } -} - -template <unsigned Digits10, class ExponentType, class Allocator> -bool cpp_dec_float<Digits10, ExponentType, Allocator>::isone() const -{ - // Check if the value of *this is identically 1 or very close to 1. - - const bool not_negative_and_is_finite = ((!neg) && (isfinite)()); - - if(not_negative_and_is_finite) - { - if((data[0u] == static_cast<boost::uint32_t>(1u)) && (exp == static_cast<ExponentType>(0))) - { - const typename array_type::const_iterator it_non_zero = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate); - return (it_non_zero == data.end()); - } - else if((data[0u] == static_cast<boost::uint32_t>(cpp_dec_float_elem_mask - 1)) && (exp == static_cast<ExponentType>(-cpp_dec_float_elem_digits10))) - { - const typename array_type::const_iterator it_non_nine = std::find_if(data.begin(), data.end(), data_elem_is_non_nine_predicate); - return (it_non_nine == data.end()); - } - } - - return false; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -bool cpp_dec_float<Digits10, ExponentType, Allocator>::isint() const -{ - if(fpclass != cpp_dec_float_finite) { return false; } - - if(iszero()) { return true; } - - if(exp < static_cast<ExponentType>(0)) { return false; } // |*this| < 1. - - const typename array_type::size_type offset_decimal_part = static_cast<typename array_type::size_type>(exp / cpp_dec_float_elem_digits10) + 1u; - - if(offset_decimal_part >= static_cast<typename array_type::size_type>(cpp_dec_float_elem_number)) - { - // The number is too large to resolve the integer part. - // It considered to be a pure integer. - return true; - } - - typename array_type::const_iterator it_non_zero = std::find_if(data.begin() + offset_decimal_part, data.end(), data_elem_is_non_zero_predicate); - - return (it_non_zero == data.end()); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -void cpp_dec_float<Digits10, ExponentType, Allocator>::extract_parts(double& mantissa, ExponentType& exponent) const -{ - // Extract the approximate parts mantissa and base-10 exponent from the input cpp_dec_float<Digits10, ExponentType, Allocator> value x. - - // Extracts the mantissa and exponent. - exponent = exp; - - boost::uint32_t p10 = static_cast<boost::uint32_t>(1u); - boost::uint32_t test = data[0u]; - - for(;;) - { - test /= static_cast<boost::uint32_t>(10u); - - if(test == static_cast<boost::uint32_t>(0u)) - { - break; - } - - p10 *= static_cast<boost::uint32_t>(10u); - ++exponent; - } - - // Establish the upper bound of limbs for extracting the double. - const int max_elem_in_double_count = static_cast<int>(static_cast<boost::int32_t>(std::numeric_limits<double>::digits10) / cpp_dec_float_elem_digits10) - + (static_cast<int>(static_cast<boost::int32_t>(std::numeric_limits<double>::digits10) % cpp_dec_float_elem_digits10) != 0 ? 1 : 0) - + 1; - - // And make sure this upper bound stays within bounds of the elems. - const std::size_t max_elem_extract_count = static_cast<std::size_t>((std::min)(static_cast<boost::int32_t>(max_elem_in_double_count), cpp_dec_float_elem_number)); - - // Extract into the mantissa the first limb, extracted as a double. - mantissa = static_cast<double>(data[0]); - double scale = 1.0; - - // Extract the rest of the mantissa piecewise from the limbs. - for(std::size_t i = 1u; i < max_elem_extract_count; i++) - { - scale /= static_cast<double>(cpp_dec_float_elem_mask); - mantissa += (static_cast<double>(data[i]) * scale); - } - - mantissa /= static_cast<double>(p10); - - if(neg) { mantissa = -mantissa; } -} - -template <unsigned Digits10, class ExponentType, class Allocator> -double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_double() const -{ - // Returns the double conversion of a cpp_dec_float<Digits10, ExponentType, Allocator>. - - // Check for non-normal cpp_dec_float<Digits10, ExponentType, Allocator>. - if(!(isfinite)()) - { - if((isnan)()) - { - return std::numeric_limits<double>::quiet_NaN(); - } - else - { - return ((!neg) ? std::numeric_limits<double>::infinity() - : -std::numeric_limits<double>::infinity()); - } - } - - cpp_dec_float<Digits10, ExponentType, Allocator> xx(*this); - if(xx.isneg()) - xx.negate(); - - // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is zero. - if(iszero() || (xx.compare(double_min()) < 0)) - { - return 0.0; - } - - // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> exceeds the maximum of double. - if(xx.compare(double_max()) > 0) - { - return ((!neg) ? std::numeric_limits<double>::infinity() - : -std::numeric_limits<double>::infinity()); - } - - std::stringstream ss; - - ss << str(std::numeric_limits<double>::digits10 + (2 + 1), std::ios_base::scientific); - - double d; - ss >> d; - - return d; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -long double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_long_double() const -{ - // Returns the long double conversion of a cpp_dec_float<Digits10, ExponentType, Allocator>. - - // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is subnormal. - if(!(isfinite)()) - { - if((isnan)()) - { - return std::numeric_limits<long double>::quiet_NaN(); - } - else - { - return ((!neg) ? std::numeric_limits<long double>::infinity() - : -std::numeric_limits<long double>::infinity()); - } - } - - cpp_dec_float<Digits10, ExponentType, Allocator> xx(*this); - if(xx.isneg()) - xx.negate(); - - // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is zero. - if(iszero() || (xx.compare(long_double_min()) < 0)) - { - return static_cast<long double>(0.0); - } - - // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> exceeds the maximum of double. - if(xx.compare(long_double_max()) > 0) - { - return ((!neg) ? std::numeric_limits<long double>::infinity() - : -std::numeric_limits<long double>::infinity()); - } - - std::stringstream ss; - - ss << str(std::numeric_limits<long double>::digits10 + (2 + 1), std::ios_base::scientific); - - long double ld; - ss >> ld; - - return ld; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -boost::long_long_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_long_long() const -{ - // Extracts a signed long long from *this. - // If (x > maximum of long long) or (x < minimum of long long), - // then the maximum or minimum of long long is returned accordingly. - - if(exp < static_cast<ExponentType>(0)) - { - return static_cast<boost::long_long_type>(0); - } - - const bool b_neg = isneg(); - - boost::ulong_long_type val; - - if((!b_neg) && (compare(long_long_max()) > 0)) - { - return (std::numeric_limits<boost::long_long_type>::max)(); - } - else if(b_neg && (compare(long_long_min()) < 0)) - { - return (std::numeric_limits<boost::long_long_type>::min)(); - } - else - { - // Extract the data into an boost::ulong_long_type value. - cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part()); - if(xn.isneg()) - xn.negate(); - - val = static_cast<boost::ulong_long_type>(xn.data[0]); - - const boost::int32_t imax = (std::min)(static_cast<boost::int32_t>(static_cast<boost::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1))); - - for(boost::int32_t i = static_cast<boost::int32_t>(1); i <= imax; i++) - { - val *= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask); - val += static_cast<boost::ulong_long_type>(xn.data[i]); - } - } - - if (!b_neg) - { - return static_cast<boost::long_long_type>(val); - } - else - { - // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in boost::long_long_type. - // See https://svn.boost.org/trac/boost/ticket/9740. - // - boost::long_long_type sval = static_cast<boost::long_long_type>(val - 1); - sval = -sval; - --sval; - return sval; - } -} - -template <unsigned Digits10, class ExponentType, class Allocator> -boost::ulong_long_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_unsigned_long_long() const -{ - // Extracts an boost::ulong_long_type from *this. - // If x exceeds the maximum of boost::ulong_long_type, - // then the maximum of boost::ulong_long_type is returned. - // If x is negative, then the boost::ulong_long_type cast of - // the long long extracted value is returned. - - if(isneg()) - { - return static_cast<boost::ulong_long_type>(extract_signed_long_long()); - } - - if(exp < static_cast<ExponentType>(0)) - { - return static_cast<boost::ulong_long_type>(0u); - } - - const cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part()); - - boost::ulong_long_type val; - - if(xn.compare(ulong_long_max()) > 0) - { - return (std::numeric_limits<boost::ulong_long_type>::max)(); - } - else - { - // Extract the data into an boost::ulong_long_type value. - val = static_cast<boost::ulong_long_type>(xn.data[0]); - - const boost::int32_t imax = (std::min)(static_cast<boost::int32_t>(static_cast<boost::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1))); - - for(boost::int32_t i = static_cast<boost::int32_t>(1); i <= imax; i++) - { - val *= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask); - val += static_cast<boost::ulong_long_type>(xn.data[i]); - } - } - - return val; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::extract_integer_part() const -{ - // Compute the signed integer part of x. - - if(!(isfinite)()) - { - return *this; - } - - if(exp < static_cast<ExponentType>(0)) - { - // The absolute value of the number is smaller than 1. - // Thus the integer part is zero. - return zero(); - } - - // Truncate the digits from the decimal part, including guard digits - // that do not belong to the integer part. - - // Make a local copy. - cpp_dec_float<Digits10, ExponentType, Allocator> x = *this; - - // Clear out the decimal portion - const size_t first_clear = (static_cast<size_t>(x.exp) / static_cast<size_t>(cpp_dec_float_elem_digits10)) + 1u; - const size_t last_clear = static_cast<size_t>(cpp_dec_float_elem_number); - - if(first_clear < last_clear) - std::fill(x.data.begin() + first_clear, x.data.begin() + last_clear, static_cast<boost::uint32_t>(0u)); - - return x; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -std::string cpp_dec_float<Digits10, ExponentType, Allocator>::str(boost::intmax_t number_of_digits, std::ios_base::fmtflags f) const -{ - if((this->isinf)()) - { - if(this->isneg()) - return "-inf"; - else if(f & std::ios_base::showpos) - return "+inf"; - else - return "inf"; - } - else if((this->isnan)()) - { - return "nan"; - } - - std::string str; - boost::intmax_t org_digits(number_of_digits); - ExponentType my_exp = order(); - - if(number_of_digits == 0) - number_of_digits = cpp_dec_float_total_digits10; - - if(f & std::ios_base::fixed) - { - number_of_digits += my_exp + 1; - } - else if(f & std::ios_base::scientific) - ++number_of_digits; - // Determine the number of elements needed to provide the requested digits from cpp_dec_float<Digits10, ExponentType, Allocator>. - const std::size_t number_of_elements = (std::min)(static_cast<std::size_t>((number_of_digits / static_cast<std::size_t>(cpp_dec_float_elem_digits10)) + 2u), - static_cast<std::size_t>(cpp_dec_float_elem_number)); - - // Extract the remaining digits from cpp_dec_float<Digits10, ExponentType, Allocator> after the decimal point. - str = boost::lexical_cast<std::string>(data[0]); - - // Extract all of the digits from cpp_dec_float<Digits10, ExponentType, Allocator>, beginning with the first data element. - for(std::size_t i = static_cast<std::size_t>(1u); i < number_of_elements; i++) - { - std::stringstream ss; - - ss << std::setw(static_cast<std::streamsize>(cpp_dec_float_elem_digits10)) - << std::setfill(static_cast<char>('0')) - << data[i]; - - str += ss.str(); - } - - bool have_leading_zeros = false; - - if(number_of_digits == 0) - { - // We only get here if the output format is "fixed" and we just need to - // round the first non-zero digit. - number_of_digits -= my_exp + 1; // reset to original value - str.insert(static_cast<std::string::size_type>(0), std::string::size_type(number_of_digits), '0'); - have_leading_zeros = true; - } - - if(number_of_digits < 0) - { - str = "0"; - if(isneg()) - str.insert(static_cast<std::string::size_type>(0), 1, '-'); - boost::multiprecision::detail::format_float_string(str, 0, number_of_digits - my_exp - 1, f, this->iszero()); - return str; - } - else - { - // Cut the output to the size of the precision. - if(str.length() > static_cast<std::string::size_type>(number_of_digits)) - { - // Get the digit after the last needed digit for rounding - const boost::uint32_t round = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(str[static_cast<std::string::size_type>(number_of_digits)]) - static_cast<boost::uint32_t>('0')); - - bool need_round_up = round >= 5u; - - if(round == 5u) - { - const boost::uint32_t ix = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(str[static_cast<std::string::size_type>(number_of_digits - 1)]) - static_cast<boost::uint32_t>('0')); - if((ix & 1u) == 0) - { - // We have an even digit followed by a 5, so we might not actually need to round up - // if all the remaining digits are zero: - if(str.find_first_not_of('0', static_cast<std::string::size_type>(number_of_digits + 1)) == std::string::npos) - { - bool all_zeros = true; - // No none-zero trailing digits in the string, now check whatever parts we didn't convert to the string: - for(std::size_t i = number_of_elements; i < data.size(); i++) - { - if(data[i]) - { - all_zeros = false; - break; - } - } - if(all_zeros) - need_round_up = false; // tie break - round to even. - } - } - } - - // Truncate the string - str.erase(static_cast<std::string::size_type>(number_of_digits)); - - if(need_round_up) - { - std::size_t ix = static_cast<std::size_t>(str.length() - 1u); - - // Every trailing 9 must be rounded up - while(ix && (static_cast<boost::int32_t>(str.at(ix)) - static_cast<boost::int32_t>('0') == static_cast<boost::int32_t>(9))) - { - str.at(ix) = static_cast<char>('0'); - --ix; - } - - if(!ix) - { - // There were nothing but trailing nines. - if(static_cast<boost::int32_t>(static_cast<boost::int32_t>(str.at(ix)) - static_cast<boost::int32_t>(0x30)) == static_cast<boost::int32_t>(9)) - { - // Increment up to the next order and adjust exponent. - str.at(ix) = static_cast<char>('1'); - ++my_exp; - } - else - { - // Round up this digit. - ++str.at(ix); - } - } - else - { - // Round up the last digit. - ++str[ix]; - } - } - } - } - - if(have_leading_zeros) - { - // We need to take the zeros back out again, and correct the exponent - // if we rounded up: - if(str[std::string::size_type(number_of_digits - 1)] != '0') - { - ++my_exp; - str.erase(0, std::string::size_type(number_of_digits - 1)); - } - else - str.erase(0, std::string::size_type(number_of_digits)); - } - - if(isneg()) - str.insert(static_cast<std::string::size_type>(0), 1, '-'); - - boost::multiprecision::detail::format_float_string(str, my_exp, org_digits, f, this->iszero()); - return str; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* const s) -{ -#ifndef BOOST_NO_EXCEPTIONS - try{ -#endif - - std::string str(s); - - // TBD: Using several regular expressions may significantly reduce - // the code complexity (and perhaps the run-time) of rd_string(). - - // Get a possible exponent and remove it. - exp = static_cast<ExponentType>(0); - - std::size_t pos; - - if( ((pos = str.find('e')) != std::string::npos) - || ((pos = str.find('E')) != std::string::npos) - ) - { - // Remove the exponent part from the string. - exp = boost::lexical_cast<ExponentType>(static_cast<const char*>(str.c_str() + (pos + 1u))); - str = str.substr(static_cast<std::size_t>(0u), pos); - } - - // Get a possible +/- sign and remove it. - neg = false; - - if(str.size()) - { - if(str[0] == '-') - { - neg = true; - str.erase(0, 1); - } - else if(str[0] == '+') - { - str.erase(0, 1); - } - } - // - // Special cases for infinities and NaN's: - // - if((str == "inf") || (str == "INF") || (str == "infinity") || (str == "INFINITY")) - { - if(neg) - { - *this = this->inf(); - this->negate(); - } - else - *this = this->inf(); - return true; - } - if((str.size() >= 3) && ((str.substr(0, 3) == "nan") || (str.substr(0, 3) == "NAN") || (str.substr(0, 3) == "NaN"))) - { - *this = this->nan(); - return true; - } - - // Remove the leading zeros for all input types. - const std::string::iterator fwd_it_leading_zero = std::find_if(str.begin(), str.end(), char_is_nonzero_predicate); - - if(fwd_it_leading_zero != str.begin()) - { - if(fwd_it_leading_zero == str.end()) - { - // The string contains nothing but leading zeros. - // This string represents zero. - operator=(zero()); - return true; - } - else - { - str.erase(str.begin(), fwd_it_leading_zero); - } - } - - // Put the input string into the standard cpp_dec_float<Digits10, ExponentType, Allocator> input form - // aaa.bbbbE+/-n, where aaa has 1...cpp_dec_float_elem_digits10, bbbb has an - // even multiple of cpp_dec_float_elem_digits10 which are possibly zero padded - // on the right-end, and n is a signed 64-bit integer which is an - // even multiple of cpp_dec_float_elem_digits10. - - // Find a possible decimal point. - pos = str.find(static_cast<char>('.')); - - if(pos != std::string::npos) - { - // Remove all trailing insignificant zeros. - const std::string::const_reverse_iterator rit_non_zero = std::find_if(str.rbegin(), str.rend(), char_is_nonzero_predicate); - - if(rit_non_zero != static_cast<std::string::const_reverse_iterator>(str.rbegin())) - { - const std::string::size_type ofs = str.length() - std::distance<std::string::const_reverse_iterator>(str.rbegin(), rit_non_zero); - str.erase(str.begin() + ofs, str.end()); - } - - // Check if the input is identically zero. - if(str == std::string(".")) - { - operator=(zero()); - return true; - } - - // Remove leading significant zeros just after the decimal point - // and adjust the exponent accordingly. - // Note that the while-loop operates only on strings of the form ".000abcd..." - // and peels away the zeros just after the decimal point. - if(str.at(static_cast<std::size_t>(0u)) == static_cast<char>('.')) - { - const std::string::iterator it_non_zero = std::find_if(str.begin() + 1u, str.end(), char_is_nonzero_predicate); - - std::size_t delta_exp = static_cast<std::size_t>(0u); - - if(str.at(static_cast<std::size_t>(1u)) == static_cast<char>('0')) - { - delta_exp = std::distance<std::string::const_iterator>(str.begin() + 1u, it_non_zero); - } - - // Bring one single digit into the mantissa and adjust the exponent accordingly. - str.erase(str.begin(), it_non_zero); - str.insert(static_cast<std::string::size_type>(1u), "."); - exp -= static_cast<ExponentType>(delta_exp + 1u); - } - } - else - { - // Input string has no decimal point: Append decimal point. - str.append("."); - } - - // Shift the decimal point such that the exponent is an even multiple of cpp_dec_float_elem_digits10. - std::size_t n_shift = static_cast<std::size_t>(0u); - const std::size_t n_exp_rem = static_cast<std::size_t>(exp % static_cast<ExponentType>(cpp_dec_float_elem_digits10)); - - if((exp % static_cast<ExponentType>(cpp_dec_float_elem_digits10)) != static_cast<ExponentType>(0)) - { - n_shift = ((exp < static_cast<ExponentType>(0)) - ? static_cast<std::size_t>(n_exp_rem + static_cast<std::size_t>(cpp_dec_float_elem_digits10)) - : static_cast<std::size_t>(n_exp_rem)); - } - - // Make sure that there are enough digits for the decimal point shift. - pos = str.find(static_cast<char>('.')); - - std::size_t pos_plus_one = static_cast<std::size_t>(pos + 1u); - - if((str.length() - pos_plus_one) < n_shift) - { - const std::size_t sz = static_cast<std::size_t>(n_shift - (str.length() - pos_plus_one)); - - str.append(std::string(sz, static_cast<char>('0'))); - } - - // Do the decimal point shift. - if(n_shift != static_cast<std::size_t>(0u)) - { - str.insert(static_cast<std::string::size_type>(pos_plus_one + n_shift), "."); - - str.erase(pos, static_cast<std::string::size_type>(1u)); - - exp -= static_cast<ExponentType>(n_shift); - } - - // Cut the size of the mantissa to <= cpp_dec_float_elem_digits10. - pos = str.find(static_cast<char>('.')); - pos_plus_one = static_cast<std::size_t>(pos + 1u); - - if(pos > static_cast<std::size_t>(cpp_dec_float_elem_digits10)) - { - const boost::int32_t n_pos = static_cast<boost::int32_t>(pos); - const boost::int32_t n_rem_is_zero = ((static_cast<boost::int32_t>(n_pos % cpp_dec_float_elem_digits10) == static_cast<boost::int32_t>(0)) ? static_cast<boost::int32_t>(1) : static_cast<boost::int32_t>(0)); - const boost::int32_t n = static_cast<boost::int32_t>(static_cast<boost::int32_t>(n_pos / cpp_dec_float_elem_digits10) - n_rem_is_zero); - - str.insert(static_cast<std::size_t>(static_cast<boost::int32_t>(n_pos - static_cast<boost::int32_t>(n * cpp_dec_float_elem_digits10))), "."); - - str.erase(pos_plus_one, static_cast<std::size_t>(1u)); - - exp += static_cast<ExponentType>(static_cast<ExponentType>(n) * static_cast<ExponentType>(cpp_dec_float_elem_digits10)); - } - - // Pad the decimal part such that its value is an even - // multiple of cpp_dec_float_elem_digits10. - pos = str.find(static_cast<char>('.')); - pos_plus_one = static_cast<std::size_t>(pos + 1u); - - const boost::int32_t n_dec = static_cast<boost::int32_t>(static_cast<boost::int32_t>(str.length() - 1u) - static_cast<boost::int32_t>(pos)); - const boost::int32_t n_rem = static_cast<boost::int32_t>(n_dec % cpp_dec_float_elem_digits10); - - boost::int32_t n_cnt = ((n_rem != static_cast<boost::int32_t>(0)) - ? static_cast<boost::int32_t>(cpp_dec_float_elem_digits10 - n_rem) - : static_cast<boost::int32_t>(0)); - - if(n_cnt != static_cast<boost::int32_t>(0)) - { - str.append(static_cast<std::size_t>(n_cnt), static_cast<char>('0')); - } - - // Truncate decimal part if it is too long. - const std::size_t max_dec = static_cast<std::size_t>((cpp_dec_float_elem_number - 1) * cpp_dec_float_elem_digits10); - - if(static_cast<std::size_t>(str.length() - pos) > max_dec) - { - str = str.substr(static_cast<std::size_t>(0u), - static_cast<std::size_t>(pos_plus_one + max_dec)); - } - - // Now the input string has the standard cpp_dec_float<Digits10, ExponentType, Allocator> input form. - // (See the comment above.) - - // Set all the data elements to 0. - std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u)); - - // Extract the data. - - // First get the digits to the left of the decimal point... - data[0u] = boost::lexical_cast<boost::uint32_t>(str.substr(static_cast<std::size_t>(0u), pos)); - - // ...then get the remaining digits to the right of the decimal point. - const std::string::size_type i_end = ((str.length() - pos_plus_one) / static_cast<std::string::size_type>(cpp_dec_float_elem_digits10)); - - for(std::string::size_type i = static_cast<std::string::size_type>(0u); i < i_end; i++) - { - const std::string::const_iterator it = str.begin() - + pos_plus_one - + (i * static_cast<std::string::size_type>(cpp_dec_float_elem_digits10)); - - data[i + 1u] = boost::lexical_cast<boost::uint32_t>(std::string(it, it + static_cast<std::string::size_type>(cpp_dec_float_elem_digits10))); - } - - // Check for overflow... - if(exp > cpp_dec_float_max_exp10) - { - const bool b_result_is_neg = neg; - - *this = inf(); - if(b_result_is_neg) - negate(); - } - - // ...and check for underflow. - if(exp <= cpp_dec_float_min_exp10) - { - if(exp == cpp_dec_float_min_exp10) - { - // Check for identity with the minimum value. - cpp_dec_float<Digits10, ExponentType, Allocator> test = *this; - - test.exp = static_cast<ExponentType>(0); - - if(test.isone()) - { - *this = zero(); - } - } - else - { - *this = zero(); - } - } - -#ifndef BOOST_NO_EXCEPTIONS - } - catch(const bad_lexical_cast&) - { - // Rethrow with better error message: - std::string msg = "Unable to parse the string \""; - msg += s; - msg += "\" as a floating point value."; - throw std::runtime_error(msg); - } -#endif - return true; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float(const double mantissa, const ExponentType exponent) - : data (), - exp (static_cast<ExponentType>(0)), - neg (false), - fpclass (cpp_dec_float_finite), - prec_elem(cpp_dec_float_elem_number) -{ - // Create *this cpp_dec_float<Digits10, ExponentType, Allocator> from a given mantissa and exponent. - // Note: This constructor does not maintain the full precision of double. - - const bool mantissa_is_iszero = (::fabs(mantissa) < ((std::numeric_limits<double>::min)() * (1.0 + std::numeric_limits<double>::epsilon()))); - - if(mantissa_is_iszero) - { - std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u)); - return; - } - - const bool b_neg = (mantissa < 0.0); - - double d = ((!b_neg) ? mantissa : -mantissa); - ExponentType e = exponent; - - while(d > 10.0) { d /= 10.0; ++e; } - while(d < 1.0) { d *= 10.0; --e; } - - boost::int32_t shift = static_cast<boost::int32_t>(e % static_cast<boost::int32_t>(cpp_dec_float_elem_digits10)); - - while(static_cast<boost::int32_t>(shift-- % cpp_dec_float_elem_digits10) != static_cast<boost::int32_t>(0)) - { - d *= 10.0; - --e; - } - - exp = e; - neg = b_neg; - - std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u)); - - static const boost::int32_t digit_ratio = static_cast<boost::int32_t>(static_cast<boost::int32_t>(std::numeric_limits<double>::digits10) / static_cast<boost::int32_t>(cpp_dec_float_elem_digits10)); - static const boost::int32_t digit_loops = static_cast<boost::int32_t>(digit_ratio + static_cast<boost::int32_t>(2)); - - for(boost::int32_t i = static_cast<boost::int32_t>(0); i < digit_loops; i++) - { - boost::uint32_t n = static_cast<boost::uint32_t>(static_cast<boost::uint64_t>(d)); - data[i] = static_cast<boost::uint32_t>(n); - d -= static_cast<double>(n); - d *= static_cast<double>(cpp_dec_float_elem_mask); - } -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator= (long double a) -{ - // Christopher Kormanyos's original code used a cast to boost::long_long_type here, but that fails - // when long double has more digits than a boost::long_long_type. - using std::frexp; - using std::ldexp; - using std::floor; - - if(a == 0) - return *this = zero(); - - if(a == 1) - return *this = one(); - - if((boost::math::isinf)(a)) - { - *this = inf(); - if(a < 0) - this->negate(); - return *this; - } - - if((boost::math::isnan)(a)) - return *this = nan(); - - int e; - long double f, term; - *this = zero(); - - f = frexp(a, &e); - // See https://svn.boost.org/trac/boost/ticket/10924 for an example of why this may go wrong: - BOOST_ASSERT((boost::math::isfinite)(f)); - - static const int shift = std::numeric_limits<int>::digits - 1; - - while(f) - { - // extract int sized bits from f: - f = ldexp(f, shift); - BOOST_ASSERT((boost::math::isfinite)(f)); - term = floor(f); - e -= shift; - *this *= pow2(shift); - if(term > 0) - add_unsigned_long_long(static_cast<unsigned>(term)); - else - sub_unsigned_long_long(static_cast<unsigned>(-term)); - f -= term; - } - - if(e != 0) - *this *= pow2(e); - - return *this; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(const boost::ulong_long_type u) -{ - std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u)); - - exp = static_cast<ExponentType>(0); - neg = false; - fpclass = cpp_dec_float_finite; - prec_elem = cpp_dec_float_elem_number; - - if(u == 0) - { - return; - } - - std::size_t i =static_cast<std::size_t>(0u); - - boost::ulong_long_type uu = u; - - boost::uint32_t temp[(std::numeric_limits<boost::ulong_long_type>::digits10 / static_cast<int>(cpp_dec_float_elem_digits10)) + 3] = { static_cast<boost::uint32_t>(0u) }; - - while(uu != static_cast<boost::ulong_long_type>(0u)) - { - temp[i] = static_cast<boost::uint32_t>(uu % static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask)); - uu = static_cast<boost::ulong_long_type>(uu / static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask)); - ++i; - } - - if(i > static_cast<std::size_t>(1u)) - { - exp += static_cast<ExponentType>((i - 1u) * static_cast<std::size_t>(cpp_dec_float_elem_digits10)); - } - - std::reverse(temp, temp + i); - std::copy(temp, temp + (std::min)(i, static_cast<std::size_t>(cpp_dec_float_elem_number)), data.begin()); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -boost::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::mul_loop_uv(boost::uint32_t* const u, const boost::uint32_t* const v, const boost::int32_t p) -{ - // - // There is a limit on how many limbs this algorithm can handle without dropping digits - // due to overflow in the carry, it is: - // - // FLOOR( (2^64 - 1) / (10^8 * 10^8) ) == 1844 - // - BOOST_STATIC_ASSERT_MSG(cpp_dec_float_elem_number < 1800, "Too many limbs in the data type for the multiplication algorithm - unsupported precision in cpp_dec_float."); - - boost::uint64_t carry = static_cast<boost::uint64_t>(0u); - - for(boost::int32_t j = static_cast<boost::int32_t>(p - 1u); j >= static_cast<boost::int32_t>(0); j--) - { - boost::uint64_t sum = carry; - - for(boost::int32_t i = j; i >= static_cast<boost::int32_t>(0); i--) - { - sum += static_cast<boost::uint64_t>(u[j - i] * static_cast<boost::uint64_t>(v[i])); - } - - u[j] = static_cast<boost::uint32_t>(sum % static_cast<boost::uint32_t>(cpp_dec_float_elem_mask)); - carry = static_cast<boost::uint64_t>(sum / static_cast<boost::uint32_t>(cpp_dec_float_elem_mask)); - } - - return static_cast<boost::uint32_t>(carry); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -boost::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::mul_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) -{ - boost::uint64_t carry = static_cast<boost::uint64_t>(0u); - - // Multiplication loop. - for(boost::int32_t j = p - 1; j >= static_cast<boost::int32_t>(0); j--) - { - const boost::uint64_t t = static_cast<boost::uint64_t>(carry + static_cast<boost::uint64_t>(u[j] * static_cast<boost::uint64_t>(n))); - carry = static_cast<boost::uint64_t>(t / static_cast<boost::uint32_t>(cpp_dec_float_elem_mask)); - u[j] = static_cast<boost::uint32_t>(t - static_cast<boost::uint64_t>(static_cast<boost::uint32_t>(cpp_dec_float_elem_mask) * static_cast<boost::uint64_t>(carry))); - } - - return static_cast<boost::uint32_t>(carry); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -boost::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::div_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) -{ - boost::uint64_t prev = static_cast<boost::uint64_t>(0u); - - for(boost::int32_t j = static_cast<boost::int32_t>(0); j < p; j++) - { - const boost::uint64_t t = static_cast<boost::uint64_t>(u[j] + static_cast<boost::uint64_t>(prev * static_cast<boost::uint32_t>(cpp_dec_float_elem_mask))); - u[j] = static_cast<boost::uint32_t>(t / n); - prev = static_cast<boost::uint64_t>(t - static_cast<boost::uint64_t>(n * static_cast<boost::uint64_t>(u[j]))); - } - - return static_cast<boost::uint32_t>(prev); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(const boost::long_long_type p) -{ - // Create a static const table of p^2 for -128 < p < +128. - // Note: The size of this table must be odd-numbered and - // symmetric about 0. - init.do_nothing(); - static const boost::array<cpp_dec_float<Digits10, ExponentType, Allocator>, 255u> p2_data = - {{ - cpp_dec_float("5.877471754111437539843682686111228389093327783860437607543758531392086297273635864257812500000000000e-39"), - cpp_dec_float("1.175494350822287507968736537222245677818665556772087521508751706278417259454727172851562500000000000e-38"), - cpp_dec_float("2.350988701644575015937473074444491355637331113544175043017503412556834518909454345703125000000000000e-38"), - cpp_dec_float("4.701977403289150031874946148888982711274662227088350086035006825113669037818908691406250000000000000e-38"), - cpp_dec_float("9.403954806578300063749892297777965422549324454176700172070013650227338075637817382812500000000000000e-38"), - cpp_dec_float("1.880790961315660012749978459555593084509864890835340034414002730045467615127563476562500000000000000e-37"), - cpp_dec_float("3.761581922631320025499956919111186169019729781670680068828005460090935230255126953125000000000000000e-37"), - cpp_dec_float("7.523163845262640050999913838222372338039459563341360137656010920181870460510253906250000000000000000e-37"), - cpp_dec_float("1.504632769052528010199982767644474467607891912668272027531202184036374092102050781250000000000000000e-36"), - cpp_dec_float("3.009265538105056020399965535288948935215783825336544055062404368072748184204101562500000000000000000e-36"), - cpp_dec_float("6.018531076210112040799931070577897870431567650673088110124808736145496368408203125000000000000000000e-36"), - cpp_dec_float("1.203706215242022408159986214115579574086313530134617622024961747229099273681640625000000000000000000e-35"), - cpp_dec_float("2.407412430484044816319972428231159148172627060269235244049923494458198547363281250000000000000000000e-35"), - cpp_dec_float("4.814824860968089632639944856462318296345254120538470488099846988916397094726562500000000000000000000e-35"), - cpp_dec_float("9.629649721936179265279889712924636592690508241076940976199693977832794189453125000000000000000000000e-35"), - cpp_dec_float("1.925929944387235853055977942584927318538101648215388195239938795566558837890625000000000000000000000e-34"), - cpp_dec_float("3.851859888774471706111955885169854637076203296430776390479877591133117675781250000000000000000000000e-34"), - cpp_dec_float("7.703719777548943412223911770339709274152406592861552780959755182266235351562500000000000000000000000e-34"), - cpp_dec_float("1.540743955509788682444782354067941854830481318572310556191951036453247070312500000000000000000000000e-33"), - cpp_dec_float("3.081487911019577364889564708135883709660962637144621112383902072906494140625000000000000000000000000e-33"), - cpp_dec_float("6.162975822039154729779129416271767419321925274289242224767804145812988281250000000000000000000000000e-33"), - cpp_dec_float("1.232595164407830945955825883254353483864385054857848444953560829162597656250000000000000000000000000e-32"), - cpp_dec_float("2.465190328815661891911651766508706967728770109715696889907121658325195312500000000000000000000000000e-32"), - cpp_dec_float("4.930380657631323783823303533017413935457540219431393779814243316650390625000000000000000000000000000e-32"), - cpp_dec_float("9.860761315262647567646607066034827870915080438862787559628486633300781250000000000000000000000000000e-32"), - cpp_dec_float("1.972152263052529513529321413206965574183016087772557511925697326660156250000000000000000000000000000e-31"), - cpp_dec_float("3.944304526105059027058642826413931148366032175545115023851394653320312500000000000000000000000000000e-31"), - cpp_dec_float("7.888609052210118054117285652827862296732064351090230047702789306640625000000000000000000000000000000e-31"), - cpp_dec_float("1.577721810442023610823457130565572459346412870218046009540557861328125000000000000000000000000000000e-30"), - cpp_dec_float("3.155443620884047221646914261131144918692825740436092019081115722656250000000000000000000000000000000e-30"), - cpp_dec_float("6.310887241768094443293828522262289837385651480872184038162231445312500000000000000000000000000000000e-30"), - cpp_dec_float("1.262177448353618888658765704452457967477130296174436807632446289062500000000000000000000000000000000e-29"), - cpp_dec_float("2.524354896707237777317531408904915934954260592348873615264892578125000000000000000000000000000000000e-29"), - cpp_dec_float("5.048709793414475554635062817809831869908521184697747230529785156250000000000000000000000000000000000e-29"), - cpp_dec_float("1.009741958682895110927012563561966373981704236939549446105957031250000000000000000000000000000000000e-28"), - cpp_dec_float("2.019483917365790221854025127123932747963408473879098892211914062500000000000000000000000000000000000e-28"), - cpp_dec_float("4.038967834731580443708050254247865495926816947758197784423828125000000000000000000000000000000000000e-28"), - cpp_dec_float("8.077935669463160887416100508495730991853633895516395568847656250000000000000000000000000000000000000e-28"), - cpp_dec_float("1.615587133892632177483220101699146198370726779103279113769531250000000000000000000000000000000000000e-27"), - cpp_dec_float("3.231174267785264354966440203398292396741453558206558227539062500000000000000000000000000000000000000e-27"), - cpp_dec_float("6.462348535570528709932880406796584793482907116413116455078125000000000000000000000000000000000000000e-27"), - cpp_dec_float("1.292469707114105741986576081359316958696581423282623291015625000000000000000000000000000000000000000e-26"), - cpp_dec_float("2.584939414228211483973152162718633917393162846565246582031250000000000000000000000000000000000000000e-26"), - cpp_dec_float("5.169878828456422967946304325437267834786325693130493164062500000000000000000000000000000000000000000e-26"), - cpp_dec_float("1.033975765691284593589260865087453566957265138626098632812500000000000000000000000000000000000000000e-25"), - cpp_dec_float("2.067951531382569187178521730174907133914530277252197265625000000000000000000000000000000000000000000e-25"), - cpp_dec_float("4.135903062765138374357043460349814267829060554504394531250000000000000000000000000000000000000000000e-25"), - cpp_dec_float("8.271806125530276748714086920699628535658121109008789062500000000000000000000000000000000000000000000e-25"), - cpp_dec_float("1.654361225106055349742817384139925707131624221801757812500000000000000000000000000000000000000000000e-24"), - cpp_dec_float("3.308722450212110699485634768279851414263248443603515625000000000000000000000000000000000000000000000e-24"), - cpp_dec_float("6.617444900424221398971269536559702828526496887207031250000000000000000000000000000000000000000000000e-24"), - cpp_dec_float("1.323488980084844279794253907311940565705299377441406250000000000000000000000000000000000000000000000e-23"), - cpp_dec_float("2.646977960169688559588507814623881131410598754882812500000000000000000000000000000000000000000000000e-23"), - cpp_dec_float("5.293955920339377119177015629247762262821197509765625000000000000000000000000000000000000000000000000e-23"), - cpp_dec_float("1.058791184067875423835403125849552452564239501953125000000000000000000000000000000000000000000000000e-22"), - cpp_dec_float("2.117582368135750847670806251699104905128479003906250000000000000000000000000000000000000000000000000e-22"), - cpp_dec_float("4.235164736271501695341612503398209810256958007812500000000000000000000000000000000000000000000000000e-22"), - cpp_dec_float("8.470329472543003390683225006796419620513916015625000000000000000000000000000000000000000000000000000e-22"), - cpp_dec_float("1.694065894508600678136645001359283924102783203125000000000000000000000000000000000000000000000000000e-21"), - cpp_dec_float("3.388131789017201356273290002718567848205566406250000000000000000000000000000000000000000000000000000e-21"), - cpp_dec_float("6.776263578034402712546580005437135696411132812500000000000000000000000000000000000000000000000000000e-21"), - cpp_dec_float("1.355252715606880542509316001087427139282226562500000000000000000000000000000000000000000000000000000e-20"), - cpp_dec_float("2.710505431213761085018632002174854278564453125000000000000000000000000000000000000000000000000000000e-20"), - cpp_dec_float("5.421010862427522170037264004349708557128906250000000000000000000000000000000000000000000000000000000e-20"), - cpp_dec_float("1.084202172485504434007452800869941711425781250000000000000000000000000000000000000000000000000000000e-19"), - cpp_dec_float("2.168404344971008868014905601739883422851562500000000000000000000000000000000000000000000000000000000e-19"), - cpp_dec_float("4.336808689942017736029811203479766845703125000000000000000000000000000000000000000000000000000000000e-19"), - cpp_dec_float("8.673617379884035472059622406959533691406250000000000000000000000000000000000000000000000000000000000e-19"), - cpp_dec_float("1.734723475976807094411924481391906738281250000000000000000000000000000000000000000000000000000000000e-18"), - cpp_dec_float("3.469446951953614188823848962783813476562500000000000000000000000000000000000000000000000000000000000e-18"), - cpp_dec_float("6.938893903907228377647697925567626953125000000000000000000000000000000000000000000000000000000000000e-18"), - cpp_dec_float("1.387778780781445675529539585113525390625000000000000000000000000000000000000000000000000000000000000e-17"), - cpp_dec_float("2.775557561562891351059079170227050781250000000000000000000000000000000000000000000000000000000000000e-17"), - cpp_dec_float("5.551115123125782702118158340454101562500000000000000000000000000000000000000000000000000000000000000e-17"), - cpp_dec_float("1.110223024625156540423631668090820312500000000000000000000000000000000000000000000000000000000000000e-16"), - cpp_dec_float("2.220446049250313080847263336181640625000000000000000000000000000000000000000000000000000000000000000e-16"), - cpp_dec_float("4.440892098500626161694526672363281250000000000000000000000000000000000000000000000000000000000000000e-16"), - cpp_dec_float("8.881784197001252323389053344726562500000000000000000000000000000000000000000000000000000000000000000e-16"), - cpp_dec_float("1.776356839400250464677810668945312500000000000000000000000000000000000000000000000000000000000000000e-15"), - cpp_dec_float("3.552713678800500929355621337890625000000000000000000000000000000000000000000000000000000000000000000e-15"), - cpp_dec_float("7.105427357601001858711242675781250000000000000000000000000000000000000000000000000000000000000000000e-15"), - cpp_dec_float("1.421085471520200371742248535156250000000000000000000000000000000000000000000000000000000000000000000e-14"), - cpp_dec_float("2.842170943040400743484497070312500000000000000000000000000000000000000000000000000000000000000000000e-14"), - cpp_dec_float("5.684341886080801486968994140625000000000000000000000000000000000000000000000000000000000000000000000e-14"), - cpp_dec_float("1.136868377216160297393798828125000000000000000000000000000000000000000000000000000000000000000000000e-13"), - cpp_dec_float("2.273736754432320594787597656250000000000000000000000000000000000000000000000000000000000000000000000e-13"), - cpp_dec_float("4.547473508864641189575195312500000000000000000000000000000000000000000000000000000000000000000000000e-13"), - cpp_dec_float("9.094947017729282379150390625000000000000000000000000000000000000000000000000000000000000000000000000e-13"), - cpp_dec_float("1.818989403545856475830078125000000000000000000000000000000000000000000000000000000000000000000000000e-12"), - cpp_dec_float("3.637978807091712951660156250000000000000000000000000000000000000000000000000000000000000000000000000e-12"), - cpp_dec_float("7.275957614183425903320312500000000000000000000000000000000000000000000000000000000000000000000000000e-12"), - cpp_dec_float("1.455191522836685180664062500000000000000000000000000000000000000000000000000000000000000000000000000e-11"), - cpp_dec_float("2.910383045673370361328125000000000000000000000000000000000000000000000000000000000000000000000000000e-11"), - cpp_dec_float("5.820766091346740722656250000000000000000000000000000000000000000000000000000000000000000000000000000e-11"), - cpp_dec_float("1.164153218269348144531250000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), - cpp_dec_float("2.328306436538696289062500000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), - cpp_dec_float("4.656612873077392578125000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), - cpp_dec_float("9.313225746154785156250000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), - cpp_dec_float("1.862645149230957031250000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), - cpp_dec_float("3.725290298461914062500000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), - cpp_dec_float("7.450580596923828125000000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), - cpp_dec_float("1.490116119384765625000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), - cpp_dec_float("2.980232238769531250000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), - cpp_dec_float("5.960464477539062500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), - cpp_dec_float("1.192092895507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), - cpp_dec_float("2.384185791015625000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), - cpp_dec_float("4.768371582031250000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), - cpp_dec_float("9.536743164062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), - cpp_dec_float("1.907348632812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), - cpp_dec_float("3.814697265625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), - cpp_dec_float("7.629394531250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), - cpp_dec_float("0.000015258789062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.000030517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.000061035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.000122070312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.000244140625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.000488281250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.000976562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.001953125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.003906250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.007812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.01562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.03125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.06250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - cpp_dec_float("0.125"), - cpp_dec_float("0.25"), - cpp_dec_float("0.5"), - one(), - two(), - cpp_dec_float(static_cast<boost::ulong_long_type>(4)), - cpp_dec_float(static_cast<boost::ulong_long_type>(8)), - cpp_dec_float(static_cast<boost::ulong_long_type>(16)), - cpp_dec_float(static_cast<boost::ulong_long_type>(32)), - cpp_dec_float(static_cast<boost::ulong_long_type>(64)), - cpp_dec_float(static_cast<boost::ulong_long_type>(128)), - cpp_dec_float(static_cast<boost::ulong_long_type>(256)), - cpp_dec_float(static_cast<boost::ulong_long_type>(512)), - cpp_dec_float(static_cast<boost::ulong_long_type>(1024)), - cpp_dec_float(static_cast<boost::ulong_long_type>(2048)), - cpp_dec_float(static_cast<boost::ulong_long_type>(4096)), - cpp_dec_float(static_cast<boost::ulong_long_type>(8192)), - cpp_dec_float(static_cast<boost::ulong_long_type>(16384)), - cpp_dec_float(static_cast<boost::ulong_long_type>(32768)), - cpp_dec_float(static_cast<boost::ulong_long_type>(65536)), - cpp_dec_float(static_cast<boost::ulong_long_type>(131072)), - cpp_dec_float(static_cast<boost::ulong_long_type>(262144)), - cpp_dec_float(static_cast<boost::ulong_long_type>(524288)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 20u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 21u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 22u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 23u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 24u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 25u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 26u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 27u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 28u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 29u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 30u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uL << 31u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 32u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 33u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 34u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 35u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 36u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 37u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 38u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 39u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 40u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 41u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 42u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 43u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 44u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 45u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 46u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 47u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 48u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 49u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 50u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 51u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 52u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 53u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 54u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 55u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 56u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 57u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 58u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 59u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 60u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 61u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 62u)), - cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 63u)), - cpp_dec_float("1.844674407370955161600000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), - cpp_dec_float("3.689348814741910323200000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), - cpp_dec_float("7.378697629483820646400000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), - cpp_dec_float("1.475739525896764129280000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), - cpp_dec_float("2.951479051793528258560000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), - cpp_dec_float("5.902958103587056517120000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), - cpp_dec_float("1.180591620717411303424000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), - cpp_dec_float("2.361183241434822606848000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), - cpp_dec_float("4.722366482869645213696000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), - cpp_dec_float("9.444732965739290427392000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), - cpp_dec_float("1.888946593147858085478400000000000000000000000000000000000000000000000000000000000000000000000000000e22"), - cpp_dec_float("3.777893186295716170956800000000000000000000000000000000000000000000000000000000000000000000000000000e22"), - cpp_dec_float("7.555786372591432341913600000000000000000000000000000000000000000000000000000000000000000000000000000e22"), - cpp_dec_float("1.511157274518286468382720000000000000000000000000000000000000000000000000000000000000000000000000000e23"), - cpp_dec_float("3.022314549036572936765440000000000000000000000000000000000000000000000000000000000000000000000000000e23"), - cpp_dec_float("6.044629098073145873530880000000000000000000000000000000000000000000000000000000000000000000000000000e23"), - cpp_dec_float("1.208925819614629174706176000000000000000000000000000000000000000000000000000000000000000000000000000e24"), - cpp_dec_float("2.417851639229258349412352000000000000000000000000000000000000000000000000000000000000000000000000000e24"), - cpp_dec_float("4.835703278458516698824704000000000000000000000000000000000000000000000000000000000000000000000000000e24"), - cpp_dec_float("9.671406556917033397649408000000000000000000000000000000000000000000000000000000000000000000000000000e24"), - cpp_dec_float("1.934281311383406679529881600000000000000000000000000000000000000000000000000000000000000000000000000e25"), - cpp_dec_float("3.868562622766813359059763200000000000000000000000000000000000000000000000000000000000000000000000000e25"), - cpp_dec_float("7.737125245533626718119526400000000000000000000000000000000000000000000000000000000000000000000000000e25"), - cpp_dec_float("1.547425049106725343623905280000000000000000000000000000000000000000000000000000000000000000000000000e26"), - cpp_dec_float("3.094850098213450687247810560000000000000000000000000000000000000000000000000000000000000000000000000e26"), - cpp_dec_float("6.189700196426901374495621120000000000000000000000000000000000000000000000000000000000000000000000000e26"), - cpp_dec_float("1.237940039285380274899124224000000000000000000000000000000000000000000000000000000000000000000000000e27"), - cpp_dec_float("2.475880078570760549798248448000000000000000000000000000000000000000000000000000000000000000000000000e27"), - cpp_dec_float("4.951760157141521099596496896000000000000000000000000000000000000000000000000000000000000000000000000e27"), - cpp_dec_float("9.903520314283042199192993792000000000000000000000000000000000000000000000000000000000000000000000000e27"), - cpp_dec_float("1.980704062856608439838598758400000000000000000000000000000000000000000000000000000000000000000000000e28"), - cpp_dec_float("3.961408125713216879677197516800000000000000000000000000000000000000000000000000000000000000000000000e28"), - cpp_dec_float("7.922816251426433759354395033600000000000000000000000000000000000000000000000000000000000000000000000e28"), - cpp_dec_float("1.584563250285286751870879006720000000000000000000000000000000000000000000000000000000000000000000000e29"), - cpp_dec_float("3.169126500570573503741758013440000000000000000000000000000000000000000000000000000000000000000000000e29"), - cpp_dec_float("6.338253001141147007483516026880000000000000000000000000000000000000000000000000000000000000000000000e29"), - cpp_dec_float("1.267650600228229401496703205376000000000000000000000000000000000000000000000000000000000000000000000e30"), - cpp_dec_float("2.535301200456458802993406410752000000000000000000000000000000000000000000000000000000000000000000000e30"), - cpp_dec_float("5.070602400912917605986812821504000000000000000000000000000000000000000000000000000000000000000000000e30"), - cpp_dec_float("1.014120480182583521197362564300800000000000000000000000000000000000000000000000000000000000000000000e31"), - cpp_dec_float("2.028240960365167042394725128601600000000000000000000000000000000000000000000000000000000000000000000e31"), - cpp_dec_float("4.056481920730334084789450257203200000000000000000000000000000000000000000000000000000000000000000000e31"), - cpp_dec_float("8.112963841460668169578900514406400000000000000000000000000000000000000000000000000000000000000000000e31"), - cpp_dec_float("1.622592768292133633915780102881280000000000000000000000000000000000000000000000000000000000000000000e32"), - cpp_dec_float("3.245185536584267267831560205762560000000000000000000000000000000000000000000000000000000000000000000e32"), - cpp_dec_float("6.490371073168534535663120411525120000000000000000000000000000000000000000000000000000000000000000000e32"), - cpp_dec_float("1.298074214633706907132624082305024000000000000000000000000000000000000000000000000000000000000000000e33"), - cpp_dec_float("2.596148429267413814265248164610048000000000000000000000000000000000000000000000000000000000000000000e33"), - cpp_dec_float("5.192296858534827628530496329220096000000000000000000000000000000000000000000000000000000000000000000e33"), - cpp_dec_float("1.038459371706965525706099265844019200000000000000000000000000000000000000000000000000000000000000000e34"), - cpp_dec_float("2.076918743413931051412198531688038400000000000000000000000000000000000000000000000000000000000000000e34"), - cpp_dec_float("4.153837486827862102824397063376076800000000000000000000000000000000000000000000000000000000000000000e34"), - cpp_dec_float("8.307674973655724205648794126752153600000000000000000000000000000000000000000000000000000000000000000e34"), - cpp_dec_float("1.661534994731144841129758825350430720000000000000000000000000000000000000000000000000000000000000000e35"), - cpp_dec_float("3.323069989462289682259517650700861440000000000000000000000000000000000000000000000000000000000000000e35"), - cpp_dec_float("6.646139978924579364519035301401722880000000000000000000000000000000000000000000000000000000000000000e35"), - cpp_dec_float("1.329227995784915872903807060280344576000000000000000000000000000000000000000000000000000000000000000e36"), - cpp_dec_float("2.658455991569831745807614120560689152000000000000000000000000000000000000000000000000000000000000000e36"), - cpp_dec_float("5.316911983139663491615228241121378304000000000000000000000000000000000000000000000000000000000000000e36"), - cpp_dec_float("1.063382396627932698323045648224275660800000000000000000000000000000000000000000000000000000000000000e37"), - cpp_dec_float("2.126764793255865396646091296448551321600000000000000000000000000000000000000000000000000000000000000e37"), - cpp_dec_float("4.253529586511730793292182592897102643200000000000000000000000000000000000000000000000000000000000000e37"), - cpp_dec_float("8.507059173023461586584365185794205286400000000000000000000000000000000000000000000000000000000000000e37"), - cpp_dec_float("1.701411834604692317316873037158841057280000000000000000000000000000000000000000000000000000000000000e38") - }}; - - if((p > static_cast<boost::long_long_type>(-128)) && (p < static_cast<boost::long_long_type>(+128))) - { - return p2_data[static_cast<std::size_t>(p + ((p2_data.size() - 1u) / 2u))]; - } - else - { - // Compute and return 2^p. - if(p < static_cast<boost::long_long_type>(0)) - { - return pow2(static_cast<boost::long_long_type>(-p)).calculate_inv(); - } - else - { - cpp_dec_float<Digits10, ExponentType, Allocator> t; - default_ops::detail::pow_imp(t, two(), p, mpl::true_()); - return t; - } - } -} - - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o) -{ - result += o; -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o) -{ - result -= o; -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o) -{ - result *= o; -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o) -{ - result /= o; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o) -{ - result.add_unsigned_long_long(o); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o) -{ - result.sub_unsigned_long_long(o); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o) -{ - result.mul_unsigned_long_long(o); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o) -{ - result.div_unsigned_long_long(o); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o) -{ - if(o < 0) - result.sub_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o)); - else - result.add_unsigned_long_long(o); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o) -{ - if(o < 0) - result.add_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o)); - else - result.sub_unsigned_long_long(o); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o) -{ - if(o < 0) - { - result.mul_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o)); - result.negate(); - } - else - result.mul_unsigned_long_long(o); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o) -{ - if(o < 0) - { - result.div_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o)); - result.negate(); - } - else - result.div_unsigned_long_long(o); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_convert_to(boost::ulong_long_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val) -{ - *result = val.extract_unsigned_long_long(); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_convert_to(boost::long_long_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val) -{ - *result = val.extract_signed_long_long(); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_convert_to(long double* result, cpp_dec_float<Digits10, ExponentType, Allocator>& val) -{ - *result = val.extract_long_double(); -} - -// -// Non member function support: -// -template <unsigned Digits10, class ExponentType, class Allocator> -inline int eval_fpclassify(const cpp_dec_float<Digits10, ExponentType, Allocator>& x) -{ - if((x.isinf)()) - return FP_INFINITE; - if((x.isnan)()) - return FP_NAN; - if(x.iszero()) - return FP_ZERO; - return FP_NORMAL; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_abs(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x) -{ - result = x; - if(x.isneg()) - result.negate(); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_fabs(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x) -{ - result = x; - if(x.isneg()) - result.negate(); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_sqrt(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x) -{ - result = x; - result.calculate_sqrt(); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_floor(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x) -{ - result = x; - if(!(x.isfinite)() || x.isint()) - { - if((x.isnan)()) - errno = EDOM; - return; - } - - if(x.isneg()) - result -= cpp_dec_float<Digits10, ExponentType, Allocator>::one(); - result = result.extract_integer_part(); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_ceil(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x) -{ - result = x; - if(!(x.isfinite)() || x.isint()) - { - if((x.isnan)()) - errno = EDOM; - return; - } - - if(!x.isneg()) - result += cpp_dec_float<Digits10, ExponentType, Allocator>::one(); - result = result.extract_integer_part(); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_trunc(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x) -{ - if(x.isint() || !(x.isfinite)()) - { - result = x; - if((x.isnan)()) - errno = EDOM; - return; - } - result = x.extract_integer_part(); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline ExponentType eval_ilogb(const cpp_dec_float<Digits10, ExponentType, Allocator>& val) -{ - if(val.iszero()) - return (std::numeric_limits<ExponentType>::min)(); - if((val.isinf)()) - return INT_MAX; - if((val.isnan)()) -#ifdef FP_ILOGBNAN - return FP_ILOGBNAN; -#else - return INT_MAX; -#endif - // Set result, to the exponent of val: - return val.order(); -} -template <unsigned Digits10, class ExponentType, class Allocator, class ArgType> -inline void eval_scalbn(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val, ArgType e_) -{ - using default_ops::eval_multiply; - const ExponentType e = static_cast<ExponentType>(e_); - cpp_dec_float<Digits10, ExponentType, Allocator> t(1.0, e); - eval_multiply(result, val, t); -} - -template <unsigned Digits10, class ExponentType, class Allocator, class ArgType> -inline void eval_ldexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, ArgType e) -{ - const boost::long_long_type the_exp = static_cast<boost::long_long_type>(e); - - if((the_exp > (std::numeric_limits<ExponentType>::max)()) || (the_exp < (std::numeric_limits<ExponentType>::min)())) - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Exponent value is out of range."))); - - result = x; - - if ((the_exp > static_cast<boost::long_long_type>(-std::numeric_limits<boost::long_long_type>::digits)) && (the_exp < static_cast<boost::long_long_type>(0))) - result.div_unsigned_long_long(1ULL << static_cast<boost::long_long_type>(-the_exp)); - else if((the_exp < static_cast<boost::long_long_type>( std::numeric_limits<boost::long_long_type>::digits)) && (the_exp > static_cast<boost::long_long_type>(0))) - result.mul_unsigned_long_long(1ULL << the_exp); - else if(the_exp != static_cast<boost::long_long_type>(0)) - result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(e); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_frexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, ExponentType* e) -{ - result = x; - - if(result.iszero() || (result.isinf)() || (result.isnan)()) - { - *e = 0; - return; - } - - if(result.isneg()) - result.negate(); - - ExponentType t = result.order(); - BOOST_MP_USING_ABS - if(abs(t) < ((std::numeric_limits<ExponentType>::max)() / 1000)) - { - t *= 1000; - t /= 301; - } - else - { - t /= 301; - t *= 1000; - } - - result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(-t); - - if(result.iszero() || (result.isinf)() || (result.isnan)()) - { - // pow2 overflowed, slip the calculation up: - result = x; - if(result.isneg()) - result.negate(); - t /= 2; - result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(-t); - } - BOOST_MP_USING_ABS - if(abs(result.order()) > 5) - { - // If our first estimate doesn't get close enough then try recursion until we do: - ExponentType e2; - cpp_dec_float<Digits10, ExponentType, Allocator> r2; - eval_frexp(r2, result, &e2); - // overflow protection: - if((t > 0) && (e2 > 0) && (t > (std::numeric_limits<ExponentType>::max)() - e2)) - BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2.")); - if((t < 0) && (e2 < 0) && (t < (std::numeric_limits<ExponentType>::min)() - e2)) - BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2.")); - t += e2; - result = r2; - } - - while(result.compare(cpp_dec_float<Digits10, ExponentType, Allocator>::one()) >= 0) - { - result /= cpp_dec_float<Digits10, ExponentType, Allocator>::two(); - ++t; - } - while(result.compare(cpp_dec_float<Digits10, ExponentType, Allocator>::half()) < 0) - { - result *= cpp_dec_float<Digits10, ExponentType, Allocator>::two(); - --t; - } - *e = t; - if(x.isneg()) - result.negate(); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline typename disable_if<is_same<ExponentType, int> >::type eval_frexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, int* e) -{ - ExponentType t; - eval_frexp(result, x, &t); - if((t > (std::numeric_limits<int>::max)()) || (t < (std::numeric_limits<int>::min)())) - BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is outside the range of an int")); - *e = static_cast<int>(t); -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline bool eval_is_zero(const cpp_dec_float<Digits10, ExponentType, Allocator>& val) -{ - return val.iszero(); -} -template <unsigned Digits10, class ExponentType, class Allocator> -inline int eval_get_sign(const cpp_dec_float<Digits10, ExponentType, Allocator>& val) -{ - return val.iszero() ? 0 : val.isneg() ? -1 : 1; -} - -template <unsigned Digits10, class ExponentType, class Allocator> -inline std::size_t hash_value(const cpp_dec_float<Digits10, ExponentType, Allocator>& val) -{ - return val.hash(); -} - -} // namespace backends - -using boost::multiprecision::backends::cpp_dec_float; - - -typedef number<cpp_dec_float<50> > cpp_dec_float_50; -typedef number<cpp_dec_float<100> > cpp_dec_float_100; - -#ifdef BOOST_NO_SFINAE_EXPR - -namespace detail{ - -template<unsigned D1, class E1, class A1, unsigned D2, class E2, class A2> -struct is_explicitly_convertible<cpp_dec_float<D1, E1, A1>, cpp_dec_float<D2, E2, A2> > : public mpl::true_ {}; - -} - -#endif - - -}} - -namespace std -{ - template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> - class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> > - { - public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = true; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10; - BOOST_STATIC_CONSTEXPR int digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10; - BOOST_STATIC_CONSTEXPR int max_digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_total_digits10; - BOOST_STATIC_CONSTEXPR ExponentType min_exponent = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp; // Type differs from int. - BOOST_STATIC_CONSTEXPR ExponentType min_exponent10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10; // Type differs from int. - BOOST_STATIC_CONSTEXPR ExponentType max_exponent = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp; // Type differs from int. - BOOST_STATIC_CONSTEXPR ExponentType max_exponent10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10; // Type differs from int. - BOOST_STATIC_CONSTEXPR int radix = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_radix; - BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_indeterminate; - BOOST_STATIC_CONSTEXPR bool has_infinity = true; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR std::float_denorm_style has_denorm = std::denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - BOOST_STATIC_CONSTEXPR bool traps = false; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> (min) () { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::min)(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> (max) () { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::max)(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> lowest () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> epsilon () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::eps(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> round_error () { return 0.5L; } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> infinity () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::inf(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> quiet_NaN () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::nan(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> signaling_NaN() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> denorm_min () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); } - }; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::digits; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::digits10; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_digits10; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_signed; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_integer; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_exact; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::radix; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::min_exponent; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::min_exponent10; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_exponent; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_exponent10; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_infinity; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_quiet_NaN; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_signaling_NaN; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_denorm; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_denorm_loss; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_iec559; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_bounded; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_modulo; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::traps; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::tinyness_before; -template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::round_style; - -#endif -} - -namespace boost{ namespace math{ - -namespace policies{ - -template <unsigned Digits10, class ExponentType, class Allocator, class Policy, boost::multiprecision::expression_template_option ExpressionTemplates> -struct precision< boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates>, Policy> -{ - // Define a local copy of cpp_dec_float_digits10 because it might differ - // from the template parameter Digits10 for small or large digit counts. - static const boost::int32_t cpp_dec_float_digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10; - - typedef typename Policy::precision_type precision_type; - typedef digits2<((cpp_dec_float_digits10 + 1LL) * 1000LL) / 301LL> digits_2; - typedef typename mpl::if_c< - ((digits_2::value <= precision_type::value) - || (Policy::precision_type::value <= 0)), - // Default case, full precision for RealType: - digits_2, - // User customized precision: - precision_type - >::type type; -}; - -} // namespace policies - -}} // namespaces boost::math - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/debug_adaptor.hpp b/contrib/restricted/boost/boost/multiprecision/debug_adaptor.hpp deleted file mode 100644 index cb61c5b59b..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/debug_adaptor.hpp +++ /dev/null @@ -1,525 +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_ - -#ifndef BOOST_MATH_DEBUG_ADAPTER_HPP -#define BOOST_MATH_DEBUG_ADAPTER_HPP - -#include <boost/multiprecision/traits/extract_exponent_type.hpp> -#include <boost/multiprecision/detail/integer_ops.hpp> - -namespace boost{ -namespace multiprecision{ -namespace backends{ - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4127) // conditional expression is constant -#endif - - template <class Backend> -struct debug_adaptor -{ - typedef typename Backend::signed_types signed_types; - typedef typename Backend::unsigned_types unsigned_types; - typedef typename Backend::float_types float_types; - typedef typename extract_exponent_type< - Backend, number_category<Backend>::value>::type exponent_type; - -private: - std::string debug_value; - Backend m_value; -public: - void update_view() - { -#ifndef BOOST_NO_EXCEPTIONS - try - { -#endif - debug_value = m_value.str(0, static_cast<std::ios_base::fmtflags>(0)); -#ifndef BOOST_NO_EXCEPTIONS - } - catch(const std::exception& e) - { - debug_value = "String conversion failed with message: \""; - debug_value += e.what(); - debug_value += "\""; - } -#endif - } - debug_adaptor() - { - update_view(); - } - debug_adaptor(const debug_adaptor& o) : debug_value(o.debug_value), m_value(o.m_value) - { - } - debug_adaptor& operator = (const debug_adaptor& o) - { - debug_value = o.debug_value; - m_value = o.m_value; - return *this; - } - template <class T> - debug_adaptor(const T& i, const typename enable_if_c<is_convertible<T, Backend>::value>::type* = 0) - : m_value(i) - { - update_view(); - } - template <class T> - debug_adaptor(const T& i, const T& j) - : m_value(i, j) - { - update_view(); - } - template <class T> - typename enable_if_c<is_arithmetic<T>::value || is_convertible<T, Backend>::value, debug_adaptor&>::type operator = (const T& i) - { - m_value = i; - update_view(); - return *this; - } - debug_adaptor& operator = (const char* s) - { - m_value = s; - update_view(); - return *this; - } - void swap(debug_adaptor& o) - { - std::swap(m_value, o.value()); - std::swap(debug_value, o.debug_value); - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f)const - { - return m_value.str(digits, f); - } - void negate() - { - m_value.negate(); - update_view(); - } - int compare(const debug_adaptor& o)const - { - return m_value.compare(o.value()); - } - template <class T> - int compare(const T& i)const - { - return m_value.compare(i); - } - Backend& value() - { - return m_value; - } - const Backend& value()const - { - return m_value; - } - template <class Archive> - void serialize(Archive& ar, const unsigned int /*version*/) - { - ar & m_value; - typedef typename Archive::is_loading tag; - if(tag::value) - update_view(); - } - static unsigned default_precision() BOOST_NOEXCEPT - { - return Backend::default_precision(); - } - static void default_precision(unsigned v) BOOST_NOEXCEPT - { - Backend::default_precision(v); - } - unsigned precision()const BOOST_NOEXCEPT - { - return value().precision(); - } - void precision(unsigned digits10) BOOST_NOEXCEPT - { - value().precision(digits10); - } -}; - -template <class Backend> -inline Backend const& unwrap_debug_type(debug_adaptor<Backend> const& val) -{ - return val.value(); -} -template <class T> -inline const T& unwrap_debug_type(const T& val) -{ - return val; -} - -#define NON_MEMBER_OP1(name, str) \ - template <class Backend>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value());\ - result.update_view();\ - } - -#define NON_MEMBER_OP2(name, str) \ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const T& a)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a));\ - result.update_view();\ - }\ - template <class Backend>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& a)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a));\ - result.update_view();\ - } - -#define NON_MEMBER_OP3(name, str) \ - template <class Backend, class T, class U>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const T& a, const U& b)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b));\ - result.update_view();\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& a, const T& b)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b));\ - result.update_view();\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const T& a, const debug_adaptor<Backend>& b)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b));\ - result.update_view();\ - }\ - template <class Backend>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& a, const debug_adaptor<Backend>& b)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b));\ - result.update_view();\ - } - -#define NON_MEMBER_OP4(name, str) \ - template <class Backend, class T, class U, class V>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const T& a, const U& b, const V& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c));\ - result.update_view();\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& a, const debug_adaptor<Backend>& b, const T& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c));\ - result.update_view();\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& a, const T& b, const debug_adaptor<Backend>& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c));\ - result.update_view();\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const T& a, const debug_adaptor<Backend>& b, const debug_adaptor<Backend>& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c));\ - result.update_view();\ - }\ - template <class Backend>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& a, const debug_adaptor<Backend>& b, const debug_adaptor<Backend>& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c));\ - result.update_view();\ - }\ - template <class Backend, class T, class U>\ - inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& a, const T& b, const U& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c));\ - result.update_view();\ - }\ - -NON_MEMBER_OP2(add, "+=") -NON_MEMBER_OP2(subtract, "-=") -NON_MEMBER_OP2(multiply, "*=") -NON_MEMBER_OP2(divide, "/=") - -template <class Backend, class R> -inline void eval_convert_to(R* result, const debug_adaptor<Backend>& val) -{ - using default_ops::eval_convert_to; - eval_convert_to(result, val.value()); -} - -template <class Backend, class Exp> -inline void eval_frexp(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& arg, Exp* exp) -{ - eval_frexp(result.value(), arg.value(), exp); - result.update_view(); -} - -template <class Backend, class Exp> -inline void eval_ldexp(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& arg, Exp exp) -{ - eval_ldexp(result.value(), arg.value(), exp); - result.update_view(); -} - -template <class Backend, class Exp> -inline void eval_scalbn(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& arg, Exp exp) -{ - using default_ops::eval_scalbn; - eval_scalbn(result.value(), arg.value(), exp); - result.update_view(); -} - -template <class Backend> -inline typename Backend::exponent_type eval_ilogb(const debug_adaptor<Backend>& arg) -{ - using default_ops::eval_ilogb; - return eval_ilogb(arg.value()); -} - -NON_MEMBER_OP2(floor, "floor") -NON_MEMBER_OP2(ceil, "ceil") -NON_MEMBER_OP2(sqrt, "sqrt") -NON_MEMBER_OP2(logb, "logb") - -template <class Backend> -inline int eval_fpclassify(const debug_adaptor<Backend>& arg) -{ - using default_ops::eval_fpclassify; - return eval_fpclassify(arg.value()); -} - -/********************************************************************* -* -* Optional arithmetic operations come next: -* -*********************************************************************/ - -NON_MEMBER_OP3(add, "+") -NON_MEMBER_OP3(subtract, "-") -NON_MEMBER_OP3(multiply, "*") -NON_MEMBER_OP3(divide, "/") -NON_MEMBER_OP3(multiply_add, "fused-multiply-add") -NON_MEMBER_OP3(multiply_subtract, "fused-multiply-subtract") -NON_MEMBER_OP4(multiply_add, "fused-multiply-add") -NON_MEMBER_OP4(multiply_subtract, "fused-multiply-subtract") - -NON_MEMBER_OP1(increment, "increment") -NON_MEMBER_OP1(decrement, "decrement") - -/********************************************************************* -* -* Optional integer operations come next: -* -*********************************************************************/ - -NON_MEMBER_OP2(modulus, "%=") -NON_MEMBER_OP3(modulus, "%") -NON_MEMBER_OP2(bitwise_or, "|=") -NON_MEMBER_OP3(bitwise_or, "|") -NON_MEMBER_OP2(bitwise_and, "&=") -NON_MEMBER_OP3(bitwise_and, "&") -NON_MEMBER_OP2(bitwise_xor, "^=") -NON_MEMBER_OP3(bitwise_xor, "^") -NON_MEMBER_OP4(qr, "quotient-and-remainder") -NON_MEMBER_OP2(complement, "~") - -template <class Backend> -inline void eval_left_shift(debug_adaptor<Backend>& arg, std::size_t a) -{ - using default_ops::eval_left_shift; - eval_left_shift(arg.value(), a); - arg.update_view();\ -} -template <class Backend> -inline void eval_left_shift(debug_adaptor<Backend>& arg, const debug_adaptor<Backend>& a, std::size_t b) -{ - using default_ops::eval_left_shift; - eval_left_shift(arg.value(), a.value(), b); - arg.update_view();\ -} -template <class Backend> -inline void eval_right_shift(debug_adaptor<Backend>& arg, std::size_t a) -{ - using default_ops::eval_right_shift; - eval_right_shift(arg.value(), a); - arg.update_view();\ -} -template <class Backend> -inline void eval_right_shift(debug_adaptor<Backend>& arg, const debug_adaptor<Backend>& a, std::size_t b) -{ - using default_ops::eval_right_shift; - eval_right_shift(arg.value(), a.value(), b); - arg.update_view();\ -} - -template <class Backend, class T> -inline unsigned eval_integer_modulus(const debug_adaptor<Backend>& arg, const T& a) -{ - using default_ops::eval_integer_modulus; - return eval_integer_modulus(arg.value(), a); -} - -template <class Backend> -inline unsigned eval_lsb(const debug_adaptor<Backend>& arg) -{ - using default_ops::eval_lsb; - return eval_lsb(arg.value()); -} - -template <class Backend> -inline unsigned eval_msb(const debug_adaptor<Backend>& arg) -{ - using default_ops::eval_msb; - return eval_msb(arg.value()); -} - -template <class Backend> -inline bool eval_bit_test(const debug_adaptor<Backend>& arg, unsigned a) -{ - using default_ops::eval_bit_test; - return eval_bit_test(arg.value(), a); -} - -template <class Backend> -inline void eval_bit_set(const debug_adaptor<Backend>& arg, unsigned a) -{ - using default_ops::eval_bit_set; - eval_bit_set(arg.value(), a); - arg.update_view();\ -} -template <class Backend> -inline void eval_bit_unset(const debug_adaptor<Backend>& arg, unsigned a) -{ - using default_ops::eval_bit_unset; - eval_bit_unset(arg.value(), a); - arg.update_view();\ -} -template <class Backend> -inline void eval_bit_flip(const debug_adaptor<Backend>& arg, unsigned a) -{ - using default_ops::eval_bit_flip; - eval_bit_flip(arg.value(), a); - arg.update_view();\ -} - -NON_MEMBER_OP3(gcd, "gcd") -NON_MEMBER_OP3(lcm, "lcm") -NON_MEMBER_OP4(powm, "powm"); - -/********************************************************************* -* -* abs/fabs: -* -*********************************************************************/ - -NON_MEMBER_OP2(abs, "abs") -NON_MEMBER_OP2(fabs, "fabs") - -/********************************************************************* -* -* Floating point functions: -* -*********************************************************************/ - -NON_MEMBER_OP2(trunc, "trunc") -NON_MEMBER_OP2(round, "round") -NON_MEMBER_OP2(exp, "exp") -NON_MEMBER_OP2(log, "log") -NON_MEMBER_OP2(log10, "log10") -NON_MEMBER_OP2(sin, "sin") -NON_MEMBER_OP2(cos, "cos") -NON_MEMBER_OP2(tan, "tan") -NON_MEMBER_OP2(asin, "asin") -NON_MEMBER_OP2(acos, "acos") -NON_MEMBER_OP2(atan, "atan") -NON_MEMBER_OP2(sinh, "sinh") -NON_MEMBER_OP2(cosh, "cosh") -NON_MEMBER_OP2(tanh, "tanh") -NON_MEMBER_OP3(fmod, "fmod") -NON_MEMBER_OP3(pow, "pow") -NON_MEMBER_OP3(atan2, "atan2") - -template <class Backend> -int eval_signbit(const debug_adaptor<Backend>& val) -{ - return eval_signbit(val.value()); -} - -template <class Backend> -std::size_t hash_value(const debug_adaptor<Backend>& val) -{ - return hash_value(val.value()); -} - -} // namespace backends - -using backends::debug_adaptor; - -template<class Backend> -struct number_category<backends::debug_adaptor<Backend> > : public number_category<Backend> {}; - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -}} // namespaces - -namespace std{ - -template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<Backend>, ExpressionTemplates> > - : public std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > -{ - typedef std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > base_type; - typedef boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<Backend>, ExpressionTemplates> number_type; -public: - static number_type (min)() BOOST_NOEXCEPT { return (base_type::min)(); } - static number_type (max)() BOOST_NOEXCEPT { return (base_type::max)(); } - static number_type lowest() BOOST_NOEXCEPT { return -(max)(); } - static number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); } - static number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; } - static number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); } - static number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); } - static number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); } - static number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); } -}; - -} // namespace std - -namespace boost{ namespace math{ - -namespace policies{ - -template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy> -struct precision< boost::multiprecision::number<boost::multiprecision::debug_adaptor<Backend>, ExpressionTemplates>, Policy> - : public precision<boost::multiprecision::number<Backend, ExpressionTemplates>, Policy> -{}; - -#undef NON_MEMBER_OP1 -#undef NON_MEMBER_OP2 -#undef NON_MEMBER_OP3 -#undef NON_MEMBER_OP4 - -} // namespace policies - -}} // namespaces boost::math - - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/detail/big_lanczos.hpp b/contrib/restricted/boost/boost/multiprecision/detail/big_lanczos.hpp deleted file mode 100644 index 0a5a154da1..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/detail/big_lanczos.hpp +++ /dev/null @@ -1,39 +0,0 @@ - -// Copyright (c) 2011 John Maddock -// Use, modification and distribution are subject to 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) - -#ifndef BOOST_MP_BIG_LANCZOS -#define BOOST_MP_BIG_LANCZOS - -#include <boost/math/bindings/detail/big_lanczos.hpp> - -namespace boost{ namespace math{ - -namespace lanczos{ - -template <class T, class Policy> -struct lanczos; - -template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy> -struct lanczos<multiprecision::number<Backend, ExpressionTemplates>, Policy> -{ - typedef typename boost::math::policies::precision<multiprecision::number<Backend, ExpressionTemplates>, Policy>::type precision_type; - typedef typename mpl::if_c< - precision_type::value && (precision_type::value <= 73), - lanczos13UDT, - typename mpl::if_c< - precision_type::value&& (precision_type::value <= 122), - lanczos22UDT, - undefined_lanczos - >::type - >::type type; -}; - -} // namespace lanczos - -}} // namespaces - -#endif - diff --git a/contrib/restricted/boost/boost/multiprecision/detail/digits.hpp b/contrib/restricted/boost/boost/multiprecision/detail/digits.hpp deleted file mode 100644 index 8752f5b5b0..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/detail/digits.hpp +++ /dev/null @@ -1,23 +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_ - -#ifndef BOOST_MP_DIGITS_HPP -#define BOOST_MP_DIGITS_HPP - -namespace boost{ namespace multiprecision{ namespace detail{ - -inline unsigned long digits10_2_2(unsigned long d10) -{ - return (d10 * 1000uL) / 301uL + ((d10 * 1000uL) % 301 ? 2u : 1u); -} - -inline unsigned long digits2_2_10(unsigned long d2) -{ - return (d2 * 301uL) / 1000uL; -} - -}}} // namespaces - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/detail/dynamic_array.hpp b/contrib/restricted/boost/boost/multiprecision/detail/dynamic_array.hpp deleted file mode 100644 index c7a467cfc3..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/detail/dynamic_array.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. -// Copyright Christopher Kormanyos 2013. 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) -// - -#ifndef BOOST_MP_DETAIL_DYNAMIC_ARRAY_HPP - #define BOOST_MP_DETAIL_DYNAMIC_ARRAY_HPP - - #include <vector> - #include <boost/multiprecision/detail/rebind.hpp> - - namespace boost { namespace multiprecision { namespace backends { namespace detail - { - template <class value_type, const boost::uint32_t elem_number, class my_allocator> - struct dynamic_array : public std::vector<value_type, typename rebind<value_type, my_allocator>::type> - { - dynamic_array() : - std::vector<value_type, typename rebind<value_type, my_allocator>::type>(static_cast<typename std::vector<value_type, typename rebind<value_type, my_allocator>::type>::size_type>(elem_number), static_cast<value_type>(0)) - { - } - - value_type* data() { return &(*(this->begin())); } - const value_type* data() const { return &(*(this->begin())); } - }; - } } } } // namespace boost::multiprecision::backends::detail - -#endif // BOOST_MP_DETAIL_DYNAMIC_ARRAY_HPP diff --git a/contrib/restricted/boost/boost/multiprecision/detail/float_string_cvt.hpp b/contrib/restricted/boost/boost/multiprecision/detail/float_string_cvt.hpp deleted file mode 100644 index 9b5774f1af..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/detail/float_string_cvt.hpp +++ /dev/null @@ -1,318 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 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_ -// -// Generic routines for converting floating point values to and from decimal strings. -// Note that these use "naive" algorithms which result in rounding error - so they -// do not round trip to and from the string representation (but should only be out -// in the last bit). -// - -#ifndef BOOST_MP_FLOAT_STRING_CVT_HPP -#define BOOST_MP_FLOAT_STRING_CVT_HPP - -#include <cctype> - -namespace boost{ namespace multiprecision{ namespace detail{ - -template <class I> -inline void round_string_up_at(std::string& s, int pos, I& expon) -{ - // - // Rounds up a string representation of a number at pos: - // - if(pos < 0) - { - s.insert(static_cast<std::string::size_type>(0), 1, '1'); - s.erase(s.size() - 1); - ++expon; - } - else if(s[pos] == '9') - { - s[pos] = '0'; - round_string_up_at(s, pos - 1, expon); - } - else - { - if((pos == 0) && (s[pos] == '0') && (s.size() == 1)) - ++expon; - ++s[pos]; - } -} - -template <class Backend> -std::string convert_to_string(Backend b, std::streamsize digits, std::ios_base::fmtflags f) -{ - using default_ops::eval_log10; - using default_ops::eval_floor; - using default_ops::eval_pow; - using default_ops::eval_convert_to; - using default_ops::eval_multiply; - using default_ops::eval_divide; - using default_ops::eval_subtract; - using default_ops::eval_fpclassify; - - typedef typename mpl::front<typename Backend::unsigned_types>::type ui_type; - typedef typename Backend::exponent_type exponent_type; - - std::string result; - bool iszero = false; - bool isneg = false; - exponent_type expon = 0; - std::streamsize org_digits = digits; - BOOST_ASSERT(digits > 0); - - int fpt = eval_fpclassify(b); - - if(fpt == (int)FP_ZERO) - { - result = "0"; - iszero = true; - } - else if(fpt == (int)FP_INFINITE) - { - if(b.compare(ui_type(0)) < 0) - return "-inf"; - else - return ((f & std::ios_base::showpos) == std::ios_base::showpos) ? "+inf" : "inf"; - } - else if(fpt == (int)FP_NAN) - { - return "nan"; - } - else - { - // - // Start by figuring out the exponent: - // - isneg = b.compare(ui_type(0)) < 0; - if(isneg) - b.negate(); - Backend t; - Backend ten; - ten = ui_type(10); - - eval_log10(t, b); - eval_floor(t, t); - eval_convert_to(&expon, t); - if(-expon > std::numeric_limits<number<Backend> >::max_exponent10 - 3) - { - int e = -expon / 2; - Backend t2; - eval_pow(t2, ten, e); - eval_multiply(t, t2, b); - eval_multiply(t, t2); - if(expon & 1) - eval_multiply(t, ten); - } - else - { - eval_pow(t, ten, -expon); - eval_multiply(t, b); - } - // - // Make sure we're between [1,10) and adjust if not: - // - if(t.compare(ui_type(1)) < 0) - { - eval_multiply(t, ui_type(10)); - --expon; - } - else if(t.compare(ui_type(10)) >= 0) - { - eval_divide(t, ui_type(10)); - ++expon; - } - Backend digit; - ui_type cdigit; - // - // Adjust the number of digits required based on formatting options: - // - if(((f & std::ios_base::fixed) == std::ios_base::fixed) && (expon != -1)) - digits += expon + 1; - if((f & std::ios_base::scientific) == std::ios_base::scientific) - ++digits; - // - // Extract the digits one at a time: - // - for(unsigned i = 0; i < digits; ++i) - { - eval_floor(digit, t); - eval_convert_to(&cdigit, digit); - result += static_cast<char>('0' + cdigit); - eval_subtract(t, digit); - eval_multiply(t, ten); - } - // - // Possibly round result: - // - if(digits >= 0) - { - eval_floor(digit, t); - eval_convert_to(&cdigit, digit); - eval_subtract(t, digit); - if((cdigit == 5) && (t.compare(ui_type(0)) == 0)) - { - // Bankers rounding: - if((*result.rbegin() - '0') & 1) - { - round_string_up_at(result, result.size() - 1, expon); - } - } - else if(cdigit >= 5) - { - round_string_up_at(result, result.size() - 1, expon); - } - } - } - while((result.size() > digits) && result.size()) - { - // We may get here as a result of rounding... - if(result.size() > 1) - result.erase(result.size() - 1); - else - { - if(expon > 0) - --expon; // so we put less padding in the result. - else - ++expon; - ++digits; - } - } - BOOST_ASSERT(org_digits >= 0); - if(isneg) - result.insert(static_cast<std::string::size_type>(0), 1, '-'); - format_float_string(result, expon, org_digits, f, iszero); - - return result; -} - -template <class Backend> -void convert_from_string(Backend& b, const char* p) -{ - using default_ops::eval_multiply; - using default_ops::eval_add; - using default_ops::eval_pow; - using default_ops::eval_divide; - - typedef typename mpl::front<typename Backend::unsigned_types>::type ui_type; - b = ui_type(0); - if(!p || (*p == 0)) - return; - - bool is_neg = false; - bool is_neg_expon = false; - static const ui_type ten = ui_type(10); - typename Backend::exponent_type expon = 0; - int digits_seen = 0; - typedef std::numeric_limits<number<Backend, et_off> > limits; - static const int max_digits = limits::is_specialized ? limits::max_digits10 + 1 : INT_MAX; - - if(*p == '+') ++p; - else if(*p == '-') - { - is_neg = true; - ++p; - } - if((std::strcmp(p, "nan") == 0) || (std::strcmp(p, "NaN") == 0) || (std::strcmp(p, "NAN") == 0)) - { - eval_divide(b, ui_type(0)); - if(is_neg) - b.negate(); - return; - } - if((std::strcmp(p, "inf") == 0) || (std::strcmp(p, "Inf") == 0) || (std::strcmp(p, "INF") == 0)) - { - b = ui_type(1); - eval_divide(b, ui_type(0)); - if(is_neg) - b.negate(); - return; - } - // - // Grab all the leading digits before the decimal point: - // - while(std::isdigit(*p)) - { - eval_multiply(b, ten); - eval_add(b, ui_type(*p - '0')); - ++p; - ++digits_seen; - } - if(*p == '.') - { - // - // Grab everything after the point, stop when we've seen - // enough digits, even if there are actually more available: - // - ++p; - while(std::isdigit(*p)) - { - eval_multiply(b, ten); - eval_add(b, ui_type(*p - '0')); - ++p; - --expon; - if(++digits_seen > max_digits) - break; - } - while(std::isdigit(*p)) - ++p; - } - // - // Parse the exponent: - // - if((*p == 'e') || (*p == 'E')) - { - ++p; - if(*p == '+') ++p; - else if(*p == '-') - { - is_neg_expon = true; - ++p; - } - typename Backend::exponent_type e2 = 0; - while(std::isdigit(*p)) - { - e2 *= 10; - e2 += (*p - '0'); - ++p; - } - if(is_neg_expon) - e2 = -e2; - expon += e2; - } - if(expon) - { - // Scale by 10^expon, note that 10^expon can be - // outside the range of our number type, even though the - // result is within range, if that looks likely, then split - // the calculation in two: - Backend t; - t = ten; - if(expon > limits::min_exponent10 + 2) - { - eval_pow(t, t, expon); - eval_multiply(b, t); - } - else - { - eval_pow(t, t, expon + digits_seen + 1); - eval_multiply(b, t); - t = ten; - eval_pow(t, t, -digits_seen - 1); - eval_multiply(b, t); - } - } - if(is_neg) - b.negate(); - if(*p) - { - // Unexpected input in string: - BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected characters in string being interpreted as a float128.")); - } -} - -}}} // namespaces - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/detail/rebind.hpp b/contrib/restricted/boost/boost/multiprecision/detail/rebind.hpp deleted file mode 100644 index 1ad0f7dec0..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/detail/rebind.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. -// Copyright Christopher Kormanyos 2013. 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) -// - -#ifndef BOOST_MP_DETAIL_REBIND_HPP - #define BOOST_MP_DETAIL_REBIND_HPP - - namespace boost { namespace multiprecision { namespace backends { namespace detail - { - template <class value_type, class my_allocator> - struct rebind - { -#ifndef BOOST_NO_CXX11_ALLOCATOR - typedef typename std::allocator_traits<my_allocator>::template rebind_alloc<value_type> type; -#else - typedef typename my_allocator::template rebind<value_type>::other type; -#endif - }; - } } } } // namespace boost::multiprecision::backends::detail - -#endif // BOOST_MP_DETAIL_REBIND_HPP diff --git a/contrib/restricted/boost/boost/multiprecision/detail/utype_helper.hpp b/contrib/restricted/boost/boost/multiprecision/detail/utype_helper.hpp deleted file mode 100644 index 000a74b474..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/detail/utype_helper.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. -// Copyright Christopher Kormanyos 2013. 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) -// - -#ifndef BOOST_MP_UTYPE_HELPER_HPP - #define BOOST_MP_UTYPE_HELPER_HPP - - #include <limits> - #include <boost/cstdint.hpp> - - namespace boost { namespace multiprecision { - namespace detail - { - template<const unsigned> struct utype_helper { typedef boost::uint64_t exact; }; - template<> struct utype_helper<0U> { typedef boost::uint8_t exact; }; - template<> struct utype_helper<1U> { typedef boost::uint8_t exact; }; - template<> struct utype_helper<2U> { typedef boost::uint8_t exact; }; - template<> struct utype_helper<3U> { typedef boost::uint8_t exact; }; - template<> struct utype_helper<4U> { typedef boost::uint8_t exact; }; - template<> struct utype_helper<5U> { typedef boost::uint8_t exact; }; - template<> struct utype_helper<6U> { typedef boost::uint8_t exact; }; - template<> struct utype_helper<7U> { typedef boost::uint8_t exact; }; - template<> struct utype_helper<8U> { typedef boost::uint8_t exact; }; - - template<> struct utype_helper<9U> { typedef boost::uint16_t exact; }; - template<> struct utype_helper<10U> { typedef boost::uint16_t exact; }; - template<> struct utype_helper<11U> { typedef boost::uint16_t exact; }; - template<> struct utype_helper<12U> { typedef boost::uint16_t exact; }; - template<> struct utype_helper<13U> { typedef boost::uint16_t exact; }; - template<> struct utype_helper<14U> { typedef boost::uint16_t exact; }; - template<> struct utype_helper<15U> { typedef boost::uint16_t exact; }; - template<> struct utype_helper<16U> { typedef boost::uint16_t exact; }; - - template<> struct utype_helper<17U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<18U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<19U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<20U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<21U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<22U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<23U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<24U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<25U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<26U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<27U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<28U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<29U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<30U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<31U> { typedef boost::uint32_t exact; }; - template<> struct utype_helper<32U> { typedef boost::uint32_t exact; }; - - template<> struct utype_helper<33U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<34U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<35U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<36U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<37U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<38U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<39U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<40U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<41U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<42U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<43U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<44U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<45U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<46U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<47U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<48U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<49U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<50U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<51U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<52U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<53U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<54U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<55U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<56U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<57U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<58U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<59U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<60U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<61U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<62U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<63U> { typedef boost::uint64_t exact; }; - template<> struct utype_helper<64U> { typedef boost::uint64_t exact; }; - - template<class unsigned_type> - int utype_prior(unsigned_type ui) - { - // TBD: Implement a templated binary search for this. - int priority_bit; - - unsigned_type priority_mask = unsigned_type(unsigned_type(1U) << (std::numeric_limits<unsigned_type>::digits - 1)); - - for(priority_bit = std::numeric_limits<unsigned_type>::digits - 1; priority_bit >= 0; --priority_bit) - { - if(unsigned_type(priority_mask & ui) != unsigned_type(0U)) - { - break; - } - - priority_mask >>= 1; - } - - return priority_bit; - } - - } } } - -#endif // BOOST_MP_UTYPE_HELPER_HPP diff --git a/contrib/restricted/boost/boost/multiprecision/float128.hpp b/contrib/restricted/boost/boost/multiprecision/float128.hpp deleted file mode 100644 index a729523881..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/float128.hpp +++ /dev/null @@ -1,734 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 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_ - -#ifndef BOOST_MP_FLOAT128_HPP -#define BOOST_MP_FLOAT128_HPP - -#include <boost/config.hpp> -#include <boost/scoped_array.hpp> -#include <boost/functional/hash.hpp> -#include <boost/multiprecision/number.hpp> - -#if defined(BOOST_INTEL) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) -# if defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION >= 1310) && defined(__GNUC__) -# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) -# define BOOST_MP_USE_FLOAT128 -# endif -# endif - -# ifndef BOOST_MP_USE_FLOAT128 -# define BOOST_MP_USE_QUAD -# endif -#endif - -#if defined(__GNUC__) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) -# define BOOST_MP_USE_FLOAT128 -#endif - -#if !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) -# error "Sorry compiler is neither GCC, not Intel, don't know how to configure this header." -#endif -#if defined(BOOST_MP_USE_FLOAT128) && defined(BOOST_MP_USE_QUAD) -# error "Oh dear, both BOOST_MP_USE_FLOAT128 and BOOST_MP_USE_QUAD are defined, which one should I be using?" -#endif - -#if defined(BOOST_MP_USE_FLOAT128) - -extern "C" { -#include <quadmath.h> -} - -typedef __float128 float128_type; - -#elif defined(BOOST_MP_USE_QUAD) - -#include <boost/multiprecision/detail/float_string_cvt.hpp> - -typedef _Quad float128_type; - -extern "C" { -_Quad __ldexpq(_Quad, int); -_Quad __frexpq(_Quad, int*); -_Quad __fabsq(_Quad); -_Quad __floorq(_Quad); -_Quad __ceilq(_Quad); -_Quad __sqrtq(_Quad); -_Quad __truncq(_Quad); -_Quad __expq(_Quad); -_Quad __powq(_Quad, _Quad); -_Quad __logq(_Quad); -_Quad __log10q(_Quad); -_Quad __sinq(_Quad); -_Quad __cosq(_Quad); -_Quad __tanq(_Quad); -_Quad __asinq(_Quad); -_Quad __acosq(_Quad); -_Quad __atanq(_Quad); -_Quad __sinhq(_Quad); -_Quad __coshq(_Quad); -_Quad __tanhq(_Quad); -_Quad __fmodq(_Quad, _Quad); -_Quad __atan2q(_Quad, _Quad); - -#define ldexpq __ldexpq -#define frexpq __frexpq -#define fabsq __fabsq -#define floorq __floorq -#define ceilq __ceilq -#define sqrtq __sqrtq -#define truncq __truncq -#define expq __expq -#define powq __powq -#define logq __logq -#define log10q __log10q -#define sinq __sinq -#define cosq __cosq -#define tanq __tanq -#define asinq __asinq -#define acosq __acosq -#define atanq __atanq -#define sinhq __sinhq -#define coshq __coshq -#define tanhq __tanhq -#define fmodq __fmodq -#define atan2q __atan2q -} - -inline _Quad isnanq(_Quad v) -{ - return v != v; -} -inline _Quad isinfq(_Quad v) -{ - return __fabsq(v) > 1.18973149535723176508575932662800702e4932Q; -} - -#endif - -namespace boost{ -namespace multiprecision{ -namespace backends{ - -struct float128_backend; - -} - -using backends::float128_backend; - -template<> -struct number_category<backends::float128_backend> : public mpl::int_<number_kind_floating_point> {}; -#if defined(BOOST_MP_USE_QUAD) -template<> -struct number_category<float128_type> : public mpl::int_<number_kind_floating_point> {}; -#endif - -typedef number<float128_backend, et_off> float128; - -namespace backends{ - -struct float128_backend -{ - typedef mpl::list<signed char, short, int, long, boost::long_long_type> signed_types; - typedef mpl::list<unsigned char, unsigned short, - unsigned int, unsigned long, boost::ulong_long_type> unsigned_types; - typedef mpl::list<float, double, long double> float_types; - typedef int exponent_type; - -private: - float128_type m_value; -public: - BOOST_CONSTEXPR float128_backend() BOOST_NOEXCEPT : m_value(0) {} - BOOST_CONSTEXPR float128_backend(const float128_backend& o) BOOST_NOEXCEPT : m_value(o.m_value) {} - float128_backend& operator = (const float128_backend& o) BOOST_NOEXCEPT - { - m_value = o.m_value; - return *this; - } - template <class T> - BOOST_CONSTEXPR float128_backend(const T& i, const typename enable_if_c<is_convertible<T, float128_type>::value>::type* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<float128_type&>() = std::declval<const T&>())) - : m_value(i) {} - template <class T> - typename enable_if_c<is_arithmetic<T>::value || is_convertible<T, float128_type>::value, float128_backend&>::type operator = (const T& i) BOOST_NOEXCEPT_IF(noexcept(std::declval<float128_type&>() = std::declval<const T&>())) - { - m_value = i; - return *this; - } - float128_backend(long double const& f) - { - if(boost::math::isinf(f)) - m_value = (f < 0) ? -1.0Q / 0.0Q : 1.0Q / 0.0Q; - else - m_value = f; - } - float128_backend& operator=(long double const& f) - { - if(boost::math::isinf(f)) - m_value = (f < 0) ? -1.0Q / 0.0Q : 1.0Q / 0.0Q; - else - m_value = f; - return *this; - } - float128_backend& operator = (const char* s) - { -#ifndef BOOST_MP_USE_QUAD - char* p_end; - m_value = strtoflt128(s, &p_end); - if(p_end - s != (std::ptrdiff_t)std::strlen(s)) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a floating point value")); - } -#else - boost::multiprecision::detail::convert_from_string(*this, s); -#endif - return *this; - } - void swap(float128_backend& o) BOOST_NOEXCEPT - { - std::swap(m_value, o.value()); - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f)const - { -#ifndef BOOST_MP_USE_QUAD - char buf[100]; - boost::scoped_array<char> buf2; - std::string format = "%"; - if(f & std::ios_base::showpos) - format += "+"; - if(f & std::ios_base::showpoint) - format += "#"; - format += ".*"; - if(digits == 0) - digits = 36; - format += "Q"; - if(f & std::ios_base::scientific) - format += "e"; - else if(f & std::ios_base::fixed) - format += "f"; - else - format += "g"; - - int v = quadmath_snprintf (buf, 100, format.c_str(), digits, m_value); - - if((v < 0) || (v >= 99)) - { - int v_max = v; - buf2.reset(new char[v+3]); - v = quadmath_snprintf (&buf2[0], v_max + 3, format.c_str(), digits, m_value); - if(v >= v_max + 3) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed.")); - } - return &buf2[0]; - } - return buf; -#else - return boost::multiprecision::detail::convert_to_string(*this, digits ? digits : 37, f); -#endif - } - void negate() BOOST_NOEXCEPT - { - m_value = -m_value; - } - int compare(const float128_backend& o)const - { - return m_value == o.m_value ? 0 : m_value < o.m_value ? -1 : 1; - } - template <class T> - int compare(const T& i)const - { - return m_value == i ? 0 : m_value < i ? -1 : 1; - } - float128_type& value() - { - return m_value; - } - const float128_type& value()const - { - return m_value; - } -}; - -inline void eval_add(float128_backend& result, const float128_backend& a) -{ - result.value() += a.value(); -} -template <class A> -inline void eval_add(float128_backend& result, const A& a) -{ - result.value() += a; -} -inline void eval_subtract(float128_backend& result, const float128_backend& a) -{ - result.value() -= a.value(); -} -template <class A> -inline void eval_subtract(float128_backend& result, const A& a) -{ - result.value() -= a; -} -inline void eval_multiply(float128_backend& result, const float128_backend& a) -{ - result.value() *= a.value(); -} -template <class A> -inline void eval_multiply(float128_backend& result, const A& a) -{ - result.value() *= a; -} -inline void eval_divide(float128_backend& result, const float128_backend& a) -{ - result.value() /= a.value(); -} -template <class A> -inline void eval_divide(float128_backend& result, const A& a) -{ - result.value() /= a; -} - -inline void eval_add(float128_backend& result, const float128_backend& a, const float128_backend& b) -{ - result.value() = a.value() + b.value(); -} -template <class A> -inline void eval_add(float128_backend& result, const float128_backend& a, const A& b) -{ - result.value() = a.value() + b; -} -inline void eval_subtract(float128_backend& result, const float128_backend& a, const float128_backend& b) -{ - result.value() = a.value() - b.value(); -} -template <class A> -inline void eval_subtract(float128_backend& result, const float128_backend& a, const A& b) -{ - result.value() = a.value() - b; -} -template <class A> -inline void eval_subtract(float128_backend& result, const A& a, const float128_backend& b) -{ - result.value() = a - b.value(); -} -inline void eval_multiply(float128_backend& result, const float128_backend& a, const float128_backend& b) -{ - result.value() = a.value() * b.value(); -} -template <class A> -inline void eval_multiply(float128_backend& result, const float128_backend& a, const A& b) -{ - result.value() = a.value() * b; -} -inline void eval_divide(float128_backend& result, const float128_backend& a, const float128_backend& b) -{ - result.value() = a.value() / b.value(); -} - -template <class R> -inline void eval_convert_to(R* result, const float128_backend& val) -{ - *result = static_cast<R>(val.value()); -} - -inline void eval_frexp(float128_backend& result, const float128_backend& arg, int* exp) -{ - result.value() = frexpq(arg.value(), exp); -} - -inline void eval_ldexp(float128_backend& result, const float128_backend& arg, int exp) -{ - result.value() = ldexpq(arg.value(), exp); -} - -inline void eval_floor(float128_backend& result, const float128_backend& arg) -{ - result.value() = floorq(arg.value()); -} -inline void eval_ceil(float128_backend& result, const float128_backend& arg) -{ - result.value() = ceilq(arg.value()); -} -inline void eval_sqrt(float128_backend& result, const float128_backend& arg) -{ - result.value() = sqrtq(arg.value()); -} -inline int eval_fpclassify(const float128_backend& arg) -{ - if(isnanq(arg.value())) - return FP_NAN; - else if(isinfq(arg.value())) - return FP_INFINITE; - else if(arg.value() == 0) - return FP_ZERO; - - float128_backend t(arg); - if(t.value() < 0) - t.negate(); - if(t.value() < 3.36210314311209350626267781732175260e-4932Q) - return FP_SUBNORMAL; - return FP_NORMAL; -} - -inline void eval_increment(float128_backend& arg) -{ - ++arg.value(); -} -inline void eval_decrement(float128_backend& arg) -{ - --arg.value(); -} - -/********************************************************************* -* -* abs/fabs: -* -*********************************************************************/ - -inline void eval_abs(float128_backend& result, const float128_backend& arg) -{ - result.value() = fabsq(arg.value()); -} -inline void eval_fabs(float128_backend& result, const float128_backend& arg) -{ - result.value() = fabsq(arg.value()); -} - -/********************************************************************* -* -* Floating point functions: -* -*********************************************************************/ - -inline void eval_trunc(float128_backend& result, const float128_backend& arg) -{ - result.value() = truncq(arg.value()); -} -/* -// -// This doesn't actually work... rely on our own default version instead. -// -inline void eval_round(float128_backend& result, const float128_backend& arg) -{ - if(isnanq(arg.value()) || isinf(arg.value())) - { - result = boost::math::policies::raise_rounding_error( - "boost::multiprecision::trunc<%1%>(%1%)", 0, - number<float128_backend, et_off>(arg), - number<float128_backend, et_off>(arg), - boost::math::policies::policy<>()).backend(); - return; - } - result.value() = roundq(arg.value()); -} -*/ - -inline void eval_exp(float128_backend& result, const float128_backend& arg) -{ - result.value() = expq(arg.value()); -} -inline void eval_log(float128_backend& result, const float128_backend& arg) -{ - result.value() = logq(arg.value()); -} -inline void eval_log10(float128_backend& result, const float128_backend& arg) -{ - result.value() = log10q(arg.value()); -} -inline void eval_sin(float128_backend& result, const float128_backend& arg) -{ - result.value() = sinq(arg.value()); -} -inline void eval_cos(float128_backend& result, const float128_backend& arg) -{ - result.value() = cosq(arg.value()); -} -inline void eval_tan(float128_backend& result, const float128_backend& arg) -{ - result.value() = tanq(arg.value()); -} -inline void eval_asin(float128_backend& result, const float128_backend& arg) -{ - result.value() = asinq(arg.value()); -} -inline void eval_acos(float128_backend& result, const float128_backend& arg) -{ - result.value() = acosq(arg.value()); -} -inline void eval_atan(float128_backend& result, const float128_backend& arg) -{ - result.value() = atanq(arg.value()); -} -inline void eval_sinh(float128_backend& result, const float128_backend& arg) -{ - result.value() = sinhq(arg.value()); -} -inline void eval_cosh(float128_backend& result, const float128_backend& arg) -{ - result.value() = coshq(arg.value()); -} -inline void eval_tanh(float128_backend& result, const float128_backend& arg) -{ - result.value() = tanhq(arg.value()); -} -inline void eval_fmod(float128_backend& result, const float128_backend& a, const float128_backend& b) -{ - result.value() = fmodq(a.value(), b.value()); -} -inline void eval_pow(float128_backend& result, const float128_backend& a, const float128_backend& b) -{ - result.value() = powq(a.value(), b.value()); -} -inline void eval_atan2(float128_backend& result, const float128_backend& a, const float128_backend& b) -{ - result.value() = atan2q(a.value(), b.value()); -} -inline void eval_multiply_add(float128_backend& result, const float128_backend& a, const float128_backend& b, const float128_backend& c) -{ - result.value() = fmaq(a.value(), b.value(), c.value()); -} - -inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const float128_backend& arg) -{ - return ::signbitq(arg.value()); -} - -inline std::size_t hash_value(const float128_backend& val) -{ - return boost::hash_value(static_cast<double>(val.value())); -} - -} // namespace backends - - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return asinhq(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return acoshq(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return atanhq(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return cbrtq(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return erfq(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return erfcq(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return expm1q(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return lgammaq(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return tgammaq(arg.backend().value()); - } - template<boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<float128_backend, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) - { - return log1pq(arg.backend().value()); - } - - template <multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates>& b) - { - return ::copysignq(a.backend().value(), b.backend().value()); - } - - inline void eval_remainder(float128_backend& result, const float128_backend& a, const float128_backend& b) - { - result.value() = remainderq(a.value(), b.value()); - } - inline void eval_remainder(float128_backend& result, const float128_backend& a, const float128_backend& b, int* pi) - { - result.value() = remquoq(a.value(), b.value(), pi); - } - -} // namespace multiprecision - -namespace math { - - using boost::multiprecision::signbit; - using boost::multiprecision::copysign; - -} // namespace math - -} // namespace boost - -namespace boost{ -namespace archive{ - -class binary_oarchive; -class binary_iarchive; - -} - -namespace serialization{ namespace float128_detail{ - -template <class Archive> -void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::false_&) -{ - // saving - // non-binary - std::string s(val.str(0, std::ios_base::scientific)); - ar & s; -} -template <class Archive> -void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::false_&) -{ - // loading - // non-binary - std::string s; - ar & s; - val = s.c_str(); -} - -template <class Archive> -void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::true_&) -{ - // saving - // binary - ar.save_binary(&val, sizeof(val)); -} -template <class Archive> -void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::true_&) -{ - // loading - // binary - ar.load_binary(&val, sizeof(val)); -} - -} // detail - -template <class Archive> -void serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, unsigned int /*version*/) -{ - typedef typename Archive::is_loading load_tag; - typedef typename mpl::bool_<boost::is_same<Archive, boost::archive::binary_oarchive>::value || boost::is_same<Archive, boost::archive::binary_iarchive>::value> binary_tag; - - float128_detail::do_serialize(ar, val, load_tag(), binary_tag()); -} - -} // namepsace archive - -} // namespace boost - -namespace std{ - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - static number_type (min)() BOOST_NOEXCEPT { return 3.36210314311209350626267781732175260e-4932Q; } - static number_type (max)() BOOST_NOEXCEPT { return 1.18973149535723176508575932662800702e4932Q; } - static number_type lowest() BOOST_NOEXCEPT { return -(max)(); } - BOOST_STATIC_CONSTEXPR int digits = 113; - BOOST_STATIC_CONSTEXPR int digits10 = 33; - BOOST_STATIC_CONSTEXPR int max_digits10 = 36; - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR int radix = 2; - static number_type epsilon() { return 1.92592994438723585305597794258492732e-34Q; } - static number_type round_error() { return 0.5; } - BOOST_STATIC_CONSTEXPR int min_exponent = -16381; - BOOST_STATIC_CONSTEXPR int min_exponent10 = min_exponent * 301L / 1000L; - BOOST_STATIC_CONSTEXPR int max_exponent = 16384; - BOOST_STATIC_CONSTEXPR int max_exponent10 = max_exponent * 301L / 1000L; - BOOST_STATIC_CONSTEXPR bool has_infinity = true; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_present; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = true; - static number_type infinity() { return 1.0q / 0.0q; } - static number_type quiet_NaN() { return number_type("nan"); } - static number_type signaling_NaN() { return 0; } - static number_type denorm_min() { return 6.475175119438025110924438958227646552e-4966Q; } - BOOST_STATIC_CONSTEXPR bool is_iec559 = true; - BOOST_STATIC_CONSTEXPR bool is_bounded = false; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = false; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest; -}; - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10; - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix; - - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10; - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss; - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before; - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm; - -} // namespace std - - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/gmp.hpp b/contrib/restricted/boost/boost/multiprecision/gmp.hpp deleted file mode 100644 index 82ac3853d1..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/gmp.hpp +++ /dev/null @@ -1,2919 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 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_0.txt) - -#ifndef BOOST_MATH_ER_GMP_BACKEND_HPP -#define BOOST_MATH_ER_GMP_BACKEND_HPP - -#include <boost/multiprecision/number.hpp> -#include <boost/multiprecision/debug_adaptor.hpp> -#include <boost/multiprecision/detail/integer_ops.hpp> -#include <boost/multiprecision/detail/big_lanczos.hpp> -#include <boost/multiprecision/detail/digits.hpp> -#include <boost/math/special_functions/fpclassify.hpp> -#include <boost/cstdint.hpp> -#include <boost/functional/hash_fwd.hpp> -// -// Some includes we need from Boost.Math, since we rely on that library to provide these functions: -// -#include <boost/math/special_functions/asinh.hpp> -#include <boost/math/special_functions/acosh.hpp> -#include <boost/math/special_functions/atanh.hpp> -#include <boost/math/special_functions/cbrt.hpp> -#include <boost/math/special_functions/expm1.hpp> -#include <boost/math/special_functions/gamma.hpp> - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable:4127) -#endif -#include <gmp.h> -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -#if defined(__MPIR_VERSION) && defined(__MPIR_VERSION_MINOR) && defined(__MPIR_VERSION_PATCHLEVEL) -# define BOOST_MP_MPIR_VERSION (__MPIR_VERSION * 10000 + __MPIR_VERSION_MINOR * 100 + __MPIR_VERSION_PATCHLEVEL) -#else -# define BOOST_MP_MPIR_VERSION 0 -#endif - -#include <cmath> -#include <limits> -#include <climits> - -namespace boost{ -namespace multiprecision{ -namespace backends{ - -#ifdef BOOST_MSVC -// warning C4127: conditional expression is constant -#pragma warning(push) -#pragma warning(disable:4127) -#endif - -template <unsigned digits10> -struct gmp_float; -struct gmp_int; -struct gmp_rational; - -} // namespace backends - -template<> -struct number_category<backends::gmp_int> : public mpl::int_<number_kind_integer>{}; -template<> -struct number_category<backends::gmp_rational> : public mpl::int_<number_kind_rational>{}; -template <unsigned digits10> -struct number_category<backends::gmp_float<digits10> > : public mpl::int_<number_kind_floating_point>{}; - -namespace backends{ -// -// Within this file, the only functions we mark as noexcept are those that manipulate -// (but don't create) an mpf_t. All other types may allocate at pretty much any time -// via a user-supplied allocator, and therefore throw. -// -namespace detail{ - -template <unsigned digits10> -struct gmp_float_imp -{ -#ifdef BOOST_HAS_LONG_LONG - typedef mpl::list<long, boost::long_long_type> signed_types; - typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; -#else - typedef mpl::list<long> signed_types; - typedef mpl::list<unsigned long> unsigned_types; -#endif - typedef mpl::list<double, long double> float_types; - typedef long exponent_type; - - gmp_float_imp() BOOST_NOEXCEPT {} - - gmp_float_imp(const gmp_float_imp& o) - { - // - // We have to do an init followed by a set here, otherwise *this may be at - // a lower precision than o: seems like mpf_init_set copies just enough bits - // to get the right value, but if it's then used in further calculations - // things go badly wrong!! - // - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - if(o.m_data[0]._mp_d) - mpf_set(m_data, o.m_data); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_float_imp(gmp_float_imp&& o) BOOST_NOEXCEPT - { - m_data[0] = o.m_data[0]; - o.m_data[0]._mp_d = 0; - } -#endif - gmp_float_imp& operator = (const gmp_float_imp& o) - { - if(m_data[0]._mp_d == 0) - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - if(o.m_data[0]._mp_d) - mpf_set(m_data, o.m_data); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_float_imp& operator = (gmp_float_imp&& o) BOOST_NOEXCEPT - { - mpf_swap(m_data, o.m_data); - return *this; - } -#endif - -#ifdef BOOST_HAS_LONG_LONG -#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) - gmp_float_imp& operator = (boost::ulong_long_type i) - { - *this = static_cast<unsigned long>(i); - return *this; - } -#else - gmp_float_imp& operator = (boost::ulong_long_type i) - { - if(m_data[0]._mp_d == 0) - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL); - unsigned shift = 0; - mpf_t t; - mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpf_set_ui(m_data, 0); - while(i) - { - mpf_set_ui(t, static_cast<unsigned long>(i & mask)); - if(shift) - mpf_mul_2exp(t, t, shift); - mpf_add(m_data, m_data, t); - shift += std::numeric_limits<unsigned long>::digits; - i >>= std::numeric_limits<unsigned long>::digits; - } - mpf_clear(t); - return *this; - } -#endif - gmp_float_imp& operator = (boost::long_long_type i) - { - if(m_data[0]._mp_d == 0) - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - bool neg = i < 0; - *this = static_cast<boost::ulong_long_type>(boost::multiprecision::detail::unsigned_abs(i)); - if(neg) - mpf_neg(m_data, m_data); - return *this; - } -#endif - gmp_float_imp& operator = (unsigned long i) - { - if(m_data[0]._mp_d == 0) - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpf_set_ui(m_data, i); - return *this; - } - gmp_float_imp& operator = (long i) - { - if(m_data[0]._mp_d == 0) - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpf_set_si(m_data, i); - return *this; - } - gmp_float_imp& operator = (double d) - { - if(m_data[0]._mp_d == 0) - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpf_set_d(m_data, d); - return *this; - } - gmp_float_imp& operator = (long double a) - { - using std::frexp; - using std::ldexp; - using std::floor; - - if(m_data[0]._mp_d == 0) - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - - if (a == 0) { - mpf_set_si(m_data, 0); - return *this; - } - - if (a == 1) { - mpf_set_si(m_data, 1); - return *this; - } - - BOOST_ASSERT(!(boost::math::isinf)(a)); - BOOST_ASSERT(!(boost::math::isnan)(a)); - - int e; - long double f, term; - mpf_set_ui(m_data, 0u); - - f = frexp(a, &e); - - static const int shift = std::numeric_limits<int>::digits - 1; - - while(f) - { - // extract int sized bits from f: - f = ldexp(f, shift); - term = floor(f); - e -= shift; - mpf_mul_2exp(m_data, m_data, shift); - if(term > 0) - mpf_add_ui(m_data, m_data, static_cast<unsigned>(term)); - else - mpf_sub_ui(m_data, m_data, static_cast<unsigned>(-term)); - f -= term; - } - if(e > 0) - mpf_mul_2exp(m_data, m_data, e); - else if(e < 0) - mpf_div_2exp(m_data, m_data, -e); - return *this; - } - gmp_float_imp& operator = (const char* s) - { - if(m_data[0]._mp_d == 0) - mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - if(0 != mpf_set_str(m_data, s, 10)) - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid floating point number."))); - return *this; - } - void swap(gmp_float_imp& o) BOOST_NOEXCEPT - { - mpf_swap(m_data, o.m_data); - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f)const - { - BOOST_ASSERT(m_data[0]._mp_d); - - bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific; - bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed; - std::streamsize org_digits(digits); - - if(scientific && digits) - ++digits; - - std::string result; - mp_exp_t e; - void *(*alloc_func_ptr) (size_t); - void *(*realloc_func_ptr) (void *, size_t, size_t); - void (*free_func_ptr) (void *, size_t); - mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr); - - if(mpf_sgn(m_data) == 0) - { - e = 0; - result = "0"; - if(fixed && digits) - ++digits; - } - else - { - char* ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data); - --e; // To match with what our formatter expects. - if(fixed && e != -1) - { - // Oops we actually need a different number of digits to what we asked for: - (*free_func_ptr)((void*)ps, std::strlen(ps) + 1); - digits += e + 1; - if(digits == 0) - { - // We need to get *all* the digits and then possibly round up, - // we end up with either "0" or "1" as the result. - ps = mpf_get_str (0, &e, 10, 0, m_data); - --e; - unsigned offset = *ps == '-' ? 1 : 0; - if(ps[offset] > '5') - { - ++e; - ps[offset] = '1'; - ps[offset + 1] = 0; - } - else if(ps[offset] == '5') - { - unsigned i = offset + 1; - bool round_up = false; - while(ps[i] != 0) - { - if(ps[i] != '0') - { - round_up = true; - break; - } - } - if(round_up) - { - ++e; - ps[offset] = '1'; - ps[offset + 1] = 0; - } - else - { - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - else - { - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - else if(digits > 0) - { - ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data); - --e; // To match with what our formatter expects. - } - else - { - ps = mpf_get_str (0, &e, 10, 1, m_data); - --e; - unsigned offset = *ps == '-' ? 1 : 0; - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - result = ps; - (*free_func_ptr)((void*)ps, std::strlen(ps) + 1); - } - boost::multiprecision::detail::format_float_string(result, e, org_digits, f, mpf_sgn(m_data) == 0); - return result; - } - ~gmp_float_imp() BOOST_NOEXCEPT - { - if(m_data[0]._mp_d) - mpf_clear(m_data); - } - void negate() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - mpf_neg(m_data, m_data); - } - int compare(const gmp_float<digits10>& o)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d); - return mpf_cmp(m_data, o.m_data); - } - int compare(long i)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - return mpf_cmp_si(m_data, i); - } - int compare(unsigned long i)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - return mpf_cmp_ui(m_data, i); - } - template <class V> - typename enable_if<is_arithmetic<V>, int>::type compare(V v)const - { - gmp_float<digits10> d; - d = v; - return compare(d); - } - mpf_t& data() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - return m_data; - } - const mpf_t& data()const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - return m_data; - } -protected: - mpf_t m_data; - static unsigned& get_default_precision() BOOST_NOEXCEPT - { - static unsigned val = 50; - return val; - } -}; - -} // namespace detail - -struct gmp_int; -struct gmp_rational; - -template <unsigned digits10> -struct gmp_float : public detail::gmp_float_imp<digits10> -{ - gmp_float() - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - } - gmp_float(const gmp_float& o) : detail::gmp_float_imp<digits10>(o) {} - template <unsigned D> - gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= digits10>::type* = 0); - template <unsigned D> - explicit gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= digits10>::type* = 0); - gmp_float(const gmp_int& o); - gmp_float(const gmp_rational& o); - gmp_float(const mpf_t val) - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpf_set(this->m_data, val); - } - gmp_float(const mpz_t val) - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpf_set_z(this->m_data, val); - } - gmp_float(const mpq_t val) - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpf_set_q(this->m_data, val); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<digits10>(static_cast<detail::gmp_float_imp<digits10>&&>(o)) {} -#endif - gmp_float& operator=(const gmp_float& o) - { - *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10> const&>(o); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT - { - *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10>&&>(o); - return *this; - } -#endif - template <unsigned D> - gmp_float& operator=(const gmp_float<D>& o); - gmp_float& operator=(const gmp_int& o); - gmp_float& operator=(const gmp_rational& o); - gmp_float& operator=(const mpf_t val) - { - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpf_set(this->m_data, val); - return *this; - } - gmp_float& operator=(const mpz_t val) - { - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpf_set_z(this->m_data, val); - return *this; - } - gmp_float& operator=(const mpq_t val) - { - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpf_set_q(this->m_data, val); - return *this; - } - template <class V> - gmp_float& operator=(const V& v) - { - *static_cast<detail::gmp_float_imp<digits10>*>(this) = v; - return *this; - } -}; - -template <> -struct gmp_float<0> : public detail::gmp_float_imp<0> -{ - gmp_float() - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - } - gmp_float(const mpf_t val) - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpf_set(this->m_data, val); - } - gmp_float(const mpz_t val) - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpf_set_z(this->m_data, val); - } - gmp_float(const mpq_t val) - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpf_set_q(this->m_data, val); - } - gmp_float(const gmp_float& o) : detail::gmp_float_imp<0>(o) {} - template <unsigned D> - gmp_float(const gmp_float<D>& o) - { - mpf_init2(this->m_data, mpf_get_prec(o.data())); - mpf_set(this->m_data, o.data()); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<0>(static_cast<detail::gmp_float_imp<0>&&>(o)) {} -#endif - gmp_float(const gmp_int& o); - gmp_float(const gmp_rational& o); - gmp_float(const gmp_float& o, unsigned digits10) - { - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpf_set(this->m_data, o.data()); - } - - gmp_float& operator=(const gmp_float& o) - { - *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> const&>(o); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT - { - *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> &&>(o); - return *this; - } -#endif - template <unsigned D> - gmp_float& operator=(const gmp_float<D>& o) - { - if(this->m_data[0]._mp_d == 0) - { - mpf_init2(this->m_data, mpf_get_prec(o.data())); - } - else - { - mpf_set_prec(this->m_data, mpf_get_prec(o.data())); - } - mpf_set(this->m_data, o.data()); - return *this; - } - gmp_float& operator=(const gmp_int& o); - gmp_float& operator=(const gmp_rational& o); - gmp_float& operator=(const mpf_t val) - { - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpf_set(this->m_data, val); - return *this; - } - gmp_float& operator=(const mpz_t val) - { - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpf_set_z(this->m_data, val); - return *this; - } - gmp_float& operator=(const mpq_t val) - { - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpf_set_q(this->m_data, val); - return *this; - } - template <class V> - gmp_float& operator=(const V& v) - { - *static_cast<detail::gmp_float_imp<0>*>(this) = v; - return *this; - } - static unsigned default_precision() BOOST_NOEXCEPT - { - return get_default_precision(); - } - static void default_precision(unsigned v) BOOST_NOEXCEPT - { - get_default_precision() = v; - } - unsigned precision()const BOOST_NOEXCEPT - { - return static_cast<unsigned>(multiprecision::detail::digits2_2_10(static_cast<unsigned long>(mpf_get_prec(this->m_data)))); - } - void precision(unsigned digits10) BOOST_NOEXCEPT - { - mpf_set_prec(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - } -}; - -template <unsigned digits10, class T> -inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_eq(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) == 0; -} -template <unsigned digits10, class T> -inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_lt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) < 0; -} -template <unsigned digits10, class T> -inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_gt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) > 0; -} - -template <unsigned D1, unsigned D2> -inline void eval_add(gmp_float<D1>& result, const gmp_float<D2>& o) -{ - mpf_add(result.data(), result.data(), o.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(gmp_float<D1>& result, const gmp_float<D2>& o) -{ - mpf_sub(result.data(), result.data(), o.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(gmp_float<D1>& result, const gmp_float<D2>& o) -{ - mpf_mul(result.data(), result.data(), o.data()); -} -template <unsigned digits10> -inline bool eval_is_zero(const gmp_float<digits10>& val) BOOST_NOEXCEPT -{ - return mpf_sgn(val.data()) == 0; -} -template <unsigned D1, unsigned D2> -inline void eval_divide(gmp_float<D1>& result, const gmp_float<D2>& o) -{ - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpf_div(result.data(), result.data(), o.data()); -} -template <unsigned digits10> -inline void eval_add(gmp_float<digits10>& result, unsigned long i) -{ - mpf_add_ui(result.data(), result.data(), i); -} -template <unsigned digits10> -inline void eval_subtract(gmp_float<digits10>& result, unsigned long i) -{ - mpf_sub_ui(result.data(), result.data(), i); -} -template <unsigned digits10> -inline void eval_multiply(gmp_float<digits10>& result, unsigned long i) -{ - mpf_mul_ui(result.data(), result.data(), i); -} -template <unsigned digits10> -inline void eval_divide(gmp_float<digits10>& result, unsigned long i) -{ - if(i == 0) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpf_div_ui(result.data(), result.data(), i); -} -template <unsigned digits10> -inline void eval_add(gmp_float<digits10>& result, long i) -{ - if(i > 0) - mpf_add_ui(result.data(), result.data(), i); - else - mpf_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -template <unsigned digits10> -inline void eval_subtract(gmp_float<digits10>& result, long i) -{ - if(i > 0) - mpf_sub_ui(result.data(), result.data(), i); - else - mpf_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -template <unsigned digits10> -inline void eval_multiply(gmp_float<digits10>& result, long i) -{ - mpf_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); - if(i < 0) - mpf_neg(result.data(), result.data()); -} -template <unsigned digits10> -inline void eval_divide(gmp_float<digits10>& result, long i) -{ - if(i == 0) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpf_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); - if(i < 0) - mpf_neg(result.data(), result.data()); -} -// -// Specialised 3 arg versions of the basic operators: -// -template <unsigned D1, unsigned D2, unsigned D3> -inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y) -{ - mpf_add(a.data(), x.data(), y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y) -{ - mpf_add_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, long y) -{ - if(y < 0) - mpf_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y)); - else - mpf_add_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_add(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y) -{ - mpf_add_ui(a.data(), y.data(), x); -} -template <unsigned D1, unsigned D2> -inline void eval_add(gmp_float<D1>& a, long x, const gmp_float<D2>& y) -{ - if(x < 0) - { - mpf_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data()); - mpf_neg(a.data(), a.data()); - } - else - mpf_add_ui(a.data(), y.data(), x); -} -template <unsigned D1, unsigned D2, unsigned D3> -inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y) -{ - mpf_sub(a.data(), x.data(), y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y) -{ - mpf_sub_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, long y) -{ - if(y < 0) - mpf_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y)); - else - mpf_sub_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y) -{ - mpf_ui_sub(a.data(), x, y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(gmp_float<D1>& a, long x, const gmp_float<D2>& y) -{ - if(x < 0) - { - mpf_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x)); - mpf_neg(a.data(), a.data()); - } - else - mpf_ui_sub(a.data(), x, y.data()); -} - -template <unsigned D1, unsigned D2, unsigned D3> -inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y) -{ - mpf_mul(a.data(), x.data(), y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y) -{ - mpf_mul_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, long y) -{ - if(y < 0) - { - mpf_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y)); - a.negate(); - } - else - mpf_mul_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y) -{ - mpf_mul_ui(a.data(), y.data(), x); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(gmp_float<D1>& a, long x, const gmp_float<D2>& y) -{ - if(x < 0) - { - mpf_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x)); - mpf_neg(a.data(), a.data()); - } - else - mpf_mul_ui(a.data(), y.data(), x); -} - -template <unsigned D1, unsigned D2, unsigned D3> -inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y) -{ - if(eval_is_zero(y)) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpf_div(a.data(), x.data(), y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y) -{ - if(y == 0) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpf_div_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, long y) -{ - if(y == 0) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - if(y < 0) - { - mpf_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y)); - a.negate(); - } - else - mpf_div_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y) -{ - if(eval_is_zero(y)) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpf_ui_div(a.data(), x, y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(gmp_float<D1>& a, long x, const gmp_float<D2>& y) -{ - if(eval_is_zero(y)) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - if(x < 0) - { - mpf_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data()); - mpf_neg(a.data(), a.data()); - } - else - mpf_ui_div(a.data(), x, y.data()); -} - -template <unsigned digits10> -inline int eval_get_sign(const gmp_float<digits10>& val) BOOST_NOEXCEPT -{ - return mpf_sgn(val.data()); -} - -template <unsigned digits10> -inline void eval_convert_to(unsigned long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT -{ - if(0 == mpf_fits_ulong_p(val.data())) - *result = (std::numeric_limits<unsigned long>::max)(); - else - *result = (unsigned long)mpf_get_ui(val.data()); -} -template <unsigned digits10> -inline void eval_convert_to(long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT -{ - if(0 == mpf_fits_slong_p(val.data())) - { - *result = (std::numeric_limits<long>::max)(); - *result *= mpf_sgn(val.data()); - } - else - *result = (long)mpf_get_si(val.data()); -} -template <unsigned digits10> -inline void eval_convert_to(double* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT -{ - *result = mpf_get_d(val.data()); -} -#ifdef BOOST_HAS_LONG_LONG -template <unsigned digits10> -inline void eval_convert_to(boost::long_long_type* result, const gmp_float<digits10>& val) -{ - gmp_float<digits10> t(val); - if(eval_get_sign(t) < 0) - t.negate(); - - long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits; - - if(digits > 0) - mpf_div_2exp(t.data(), t.data(), digits); - - if(!mpf_fits_slong_p(t.data())) - { - if(eval_get_sign(val) < 0) - *result = (std::numeric_limits<boost::long_long_type>::min)(); - else - *result = (std::numeric_limits<boost::long_long_type>::max)(); - return; - }; - - *result = mpf_get_si(t.data()); - while(digits > 0) - { - *result <<= digits; - digits -= std::numeric_limits<unsigned long>::digits; - mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits); - unsigned long l = (unsigned long)mpf_get_ui(t.data()); - if(digits < 0) - l >>= -digits; - *result |= l; - } - if(eval_get_sign(val) < 0) - *result = -*result; -} -template <unsigned digits10> -inline void eval_convert_to(boost::ulong_long_type* result, const gmp_float<digits10>& val) -{ - gmp_float<digits10> t(val); - - long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits; - - if(digits > 0) - mpf_div_2exp(t.data(), t.data(), digits); - - if(!mpf_fits_ulong_p(t.data())) - { - *result = (std::numeric_limits<boost::long_long_type>::max)(); - return; - } - - *result = mpf_get_ui(t.data()); - while(digits > 0) - { - *result <<= digits; - digits -= std::numeric_limits<unsigned long>::digits; - mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits); - unsigned long l = (unsigned long)mpf_get_ui(t.data()); - if(digits < 0) - l >>= -digits; - *result |= l; - } -} -#endif - -// -// Native non-member operations: -// -template <unsigned Digits10> -inline void eval_sqrt(gmp_float<Digits10>& result, const gmp_float<Digits10>& val) -{ - mpf_sqrt(result.data(), val.data()); -} - -template <unsigned Digits10> -inline void eval_abs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val) -{ - mpf_abs(result.data(), val.data()); -} - -template <unsigned Digits10> -inline void eval_fabs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val) -{ - mpf_abs(result.data(), val.data()); -} -template <unsigned Digits10> -inline void eval_ceil(gmp_float<Digits10>& result, const gmp_float<Digits10>& val) -{ - mpf_ceil(result.data(), val.data()); -} -template <unsigned Digits10> -inline void eval_floor(gmp_float<Digits10>& result, const gmp_float<Digits10>& val) -{ - mpf_floor(result.data(), val.data()); -} -template <unsigned Digits10> -inline void eval_trunc(gmp_float<Digits10>& result, const gmp_float<Digits10>& val) -{ - mpf_trunc(result.data(), val.data()); -} -template <unsigned Digits10> -inline void eval_ldexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long e) -{ - if(e > 0) - mpf_mul_2exp(result.data(), val.data(), e); - else if(e < 0) - mpf_div_2exp(result.data(), val.data(), -e); - else - result = val; -} -template <unsigned Digits10> -inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, int* e) -{ -#if (BOOST_MP_MPIR_VERSION >= 20600) && (BOOST_MP_MPIR_VERSION < 30000) - mpir_si v; - mpf_get_d_2exp(&v, val.data()); -#else - long v; - mpf_get_d_2exp(&v, val.data()); -#endif - *e = v; - eval_ldexp(result, val, -v); -} -template <unsigned Digits10> -inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long* e) -{ -#if (BOOST_MP_MPIR_VERSION >= 20600) && (BOOST_MP_MPIR_VERSION < 30000) - mpir_si v; - mpf_get_d_2exp(&v, val.data()); - *e = v; - eval_ldexp(result, val, -v); -#else - mpf_get_d_2exp(e, val.data()); - eval_ldexp(result, val, -*e); -#endif -} - -template <unsigned Digits10> -inline std::size_t hash_value(const gmp_float<Digits10>& val) -{ - std::size_t result = 0; - for(int i = 0; i < std::abs(val.data()[0]._mp_size); ++i) - boost::hash_combine(result, val.data()[0]._mp_d[i]); - boost::hash_combine(result, val.data()[0]._mp_exp); - boost::hash_combine(result, val.data()[0]._mp_size); - return result; -} - -struct gmp_int -{ -#ifdef BOOST_HAS_LONG_LONG - typedef mpl::list<long, boost::long_long_type> signed_types; - typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; -#else - typedef mpl::list<long> signed_types; - typedef mpl::list<unsigned long> unsigned_types; -#endif - typedef mpl::list<double, long double> float_types; - - gmp_int() - { - mpz_init(this->m_data); - } - gmp_int(const gmp_int& o) - { - if(o.m_data[0]._mp_d) - mpz_init_set(m_data, o.m_data); - else - mpz_init(this->m_data); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_int(gmp_int&& o) BOOST_NOEXCEPT - { - m_data[0] = o.m_data[0]; - o.m_data[0]._mp_d = 0; - } -#endif - explicit gmp_int(const mpf_t val) - { - mpz_init(this->m_data); - mpz_set_f(this->m_data, val); - } - gmp_int(const mpz_t val) - { - mpz_init_set(this->m_data, val); - } - explicit gmp_int(const mpq_t val) - { - mpz_init(this->m_data); - mpz_set_q(this->m_data, val); - } - template <unsigned Digits10> - explicit gmp_int(const gmp_float<Digits10>& o) - { - mpz_init(this->m_data); - mpz_set_f(this->m_data, o.data()); - } - explicit gmp_int(const gmp_rational& o); - gmp_int& operator = (const gmp_int& o) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set(m_data, o.m_data); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_int& operator = (gmp_int&& o) BOOST_NOEXCEPT - { - mpz_swap(m_data, o.m_data); - return *this; - } -#endif -#ifdef BOOST_HAS_LONG_LONG -#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) - gmp_int& operator = (boost::ulong_long_type i) - { - *this = static_cast<unsigned long>(i); - return *this; - } -#else - gmp_int& operator = (boost::ulong_long_type i) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL); - unsigned shift = 0; - mpz_t t; - mpz_set_ui(m_data, 0); - mpz_init_set_ui(t, 0); - while(i) - { - mpz_set_ui(t, static_cast<unsigned long>(i & mask)); - if(shift) - mpz_mul_2exp(t, t, shift); - mpz_add(m_data, m_data, t); - shift += std::numeric_limits<unsigned long>::digits; - i >>= std::numeric_limits<unsigned long>::digits; - } - mpz_clear(t); - return *this; - } -#endif - gmp_int& operator = (boost::long_long_type i) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - bool neg = i < 0; - *this = boost::multiprecision::detail::unsigned_abs(i); - if(neg) - mpz_neg(m_data, m_data); - return *this; - } -#endif - gmp_int& operator = (unsigned long i) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set_ui(m_data, i); - return *this; - } - gmp_int& operator = (long i) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set_si(m_data, i); - return *this; - } - gmp_int& operator = (double d) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set_d(m_data, d); - return *this; - } - gmp_int& operator = (long double a) - { - using std::frexp; - using std::ldexp; - using std::floor; - - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - - if (a == 0) { - mpz_set_si(m_data, 0); - return *this; - } - - if (a == 1) { - mpz_set_si(m_data, 1); - return *this; - } - - BOOST_ASSERT(!(boost::math::isinf)(a)); - BOOST_ASSERT(!(boost::math::isnan)(a)); - - int e; - long double f, term; - mpz_set_ui(m_data, 0u); - - f = frexp(a, &e); - - static const int shift = std::numeric_limits<int>::digits - 1; - - while(f) - { - // extract int sized bits from f: - f = ldexp(f, shift); - term = floor(f); - e -= shift; - mpz_mul_2exp(m_data, m_data, shift); - if(term > 0) - mpz_add_ui(m_data, m_data, static_cast<unsigned>(term)); - else - mpz_sub_ui(m_data, m_data, static_cast<unsigned>(-term)); - f -= term; - } - if(e > 0) - mpz_mul_2exp(m_data, m_data, e); - else if(e < 0) - mpz_div_2exp(m_data, m_data, -e); - return *this; - } - gmp_int& operator = (const char* s) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - std::size_t n = s ? std::strlen(s) : 0; - int radix = 10; - if(n && (*s == '0')) - { - if((n > 1) && ((s[1] == 'x') || (s[1] == 'X'))) - { - radix = 16; - s +=2; - n -= 2; - } - else - { - radix = 8; - n -= 1; - } - } - if(n) - { - if(0 != mpz_set_str(m_data, s, radix)) - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid integer."))); - } - else - mpz_set_ui(m_data, 0); - return *this; - } - gmp_int& operator=(const mpf_t val) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set_f(this->m_data, val); - return *this; - } - gmp_int& operator=(const mpz_t val) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set(this->m_data, val); - return *this; - } - gmp_int& operator=(const mpq_t val) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set_q(this->m_data, val); - return *this; - } - template <unsigned Digits10> - gmp_int& operator=(const gmp_float<Digits10>& o) - { - if(m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set_f(this->m_data, o.data()); - return *this; - } - gmp_int& operator=(const gmp_rational& o); - void swap(gmp_int& o) - { - mpz_swap(m_data, o.m_data); - } - std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const - { - BOOST_ASSERT(m_data[0]._mp_d); - - int base = 10; - if((f & std::ios_base::oct) == std::ios_base::oct) - base = 8; - else if((f & std::ios_base::hex) == std::ios_base::hex) - base = 16; - // - // sanity check, bases 8 and 16 are only available for positive numbers: - // - if((base != 10) && (mpz_sgn(m_data) < 0)) - BOOST_THROW_EXCEPTION(std::runtime_error("Formatted output in bases 8 or 16 is only available for positive numbers")); - void *(*alloc_func_ptr) (size_t); - void *(*realloc_func_ptr) (void *, size_t, size_t); - void (*free_func_ptr) (void *, size_t); - const char* ps = mpz_get_str (0, base, m_data); - std::string s = ps; - mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr); - (*free_func_ptr)((void*)ps, std::strlen(ps) + 1); - - if((base != 10) && (f & std::ios_base::showbase)) - { - int pos = s[0] == '-' ? 1 : 0; - const char* pp = base == 8 ? "0" : "0x"; - s.insert(static_cast<std::string::size_type>(pos), pp); - } - if((f & std::ios_base::showpos) && (s[0] != '-')) - s.insert(static_cast<std::string::size_type>(0), 1, '+'); - - return s; - } - ~gmp_int() BOOST_NOEXCEPT - { - if(m_data[0]._mp_d) - mpz_clear(m_data); - } - void negate() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - mpz_neg(m_data, m_data); - } - int compare(const gmp_int& o)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d); - return mpz_cmp(m_data, o.m_data); - } - int compare(long i)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - return mpz_cmp_si(m_data, i); - } - int compare(unsigned long i)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - return mpz_cmp_ui(m_data, i); - } - template <class V> - int compare(V v)const - { - gmp_int d; - d = v; - return compare(d); - } - mpz_t& data() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - return m_data; - } - const mpz_t& data()const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mp_d); - return m_data; - } -protected: - mpz_t m_data; -}; - -template <class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const gmp_int& a, const T& b) -{ - return a.compare(b) == 0; -} -template <class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const gmp_int& a, const T& b) -{ - return a.compare(b) < 0; -} -template <class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const gmp_int& a, const T& b) -{ - return a.compare(b) > 0; -} - -inline bool eval_is_zero(const gmp_int& val) -{ - return mpz_sgn(val.data()) == 0; -} -inline void eval_add(gmp_int& t, const gmp_int& o) -{ - mpz_add(t.data(), t.data(), o.data()); -} -inline void eval_multiply_add(gmp_int& t, const gmp_int& a, const gmp_int& b) -{ - mpz_addmul(t.data(), a.data(), b.data()); -} -inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, const gmp_int& b) -{ - mpz_submul(t.data(), a.data(), b.data()); -} -inline void eval_subtract(gmp_int& t, const gmp_int& o) -{ - mpz_sub(t.data(), t.data(), o.data()); -} -inline void eval_multiply(gmp_int& t, const gmp_int& o) -{ - mpz_mul(t.data(), t.data(), o.data()); -} -inline void eval_divide(gmp_int& t, const gmp_int& o) -{ - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q(t.data(), t.data(), o.data()); -} -inline void eval_modulus(gmp_int& t, const gmp_int& o) -{ - mpz_tdiv_r(t.data(), t.data(), o.data()); -} -inline void eval_add(gmp_int& t, unsigned long i) -{ - mpz_add_ui(t.data(), t.data(), i); -} -inline void eval_multiply_add(gmp_int& t, const gmp_int& a, unsigned long i) -{ - mpz_addmul_ui(t.data(), a.data(), i); -} -inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, unsigned long i) -{ - mpz_submul_ui(t.data(), a.data(), i); -} -inline void eval_subtract(gmp_int& t, unsigned long i) -{ - mpz_sub_ui(t.data(), t.data(), i); -} -inline void eval_multiply(gmp_int& t, unsigned long i) -{ - mpz_mul_ui(t.data(), t.data(), i); -} -inline void eval_modulus(gmp_int& t, unsigned long i) -{ - mpz_tdiv_r_ui(t.data(), t.data(), i); -} -inline void eval_divide(gmp_int& t, unsigned long i) -{ - if(i == 0) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q_ui(t.data(), t.data(), i); -} -inline void eval_add(gmp_int& t, long i) -{ - if(i > 0) - mpz_add_ui(t.data(), t.data(), i); - else - mpz_sub_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -inline void eval_multiply_add(gmp_int& t, const gmp_int& a, long i) -{ - if(i > 0) - mpz_addmul_ui(t.data(), a.data(), i); - else - mpz_submul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, long i) -{ - if(i > 0) - mpz_submul_ui(t.data(), a.data(), i); - else - mpz_addmul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -inline void eval_subtract(gmp_int& t, long i) -{ - if(i > 0) - mpz_sub_ui(t.data(), t.data(), i); - else - mpz_add_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -inline void eval_multiply(gmp_int& t, long i) -{ - mpz_mul_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); - if(i < 0) - mpz_neg(t.data(), t.data()); -} -inline void eval_modulus(gmp_int& t, long i) -{ - mpz_tdiv_r_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -inline void eval_divide(gmp_int& t, long i) -{ - if(i == 0) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); - if(i < 0) - mpz_neg(t.data(), t.data()); -} -template <class UI> -inline void eval_left_shift(gmp_int& t, UI i) -{ - mpz_mul_2exp(t.data(), t.data(), static_cast<unsigned long>(i)); -} -template <class UI> -inline void eval_right_shift(gmp_int& t, UI i) -{ - mpz_fdiv_q_2exp(t.data(), t.data(), static_cast<unsigned long>(i)); -} -template <class UI> -inline void eval_left_shift(gmp_int& t, const gmp_int& v, UI i) -{ - mpz_mul_2exp(t.data(), v.data(), static_cast<unsigned long>(i)); -} -template <class UI> -inline void eval_right_shift(gmp_int& t, const gmp_int& v, UI i) -{ - mpz_fdiv_q_2exp(t.data(), v.data(), static_cast<unsigned long>(i)); -} - -inline void eval_bitwise_and(gmp_int& result, const gmp_int& v) -{ - mpz_and(result.data(), result.data(), v.data()); -} - -inline void eval_bitwise_or(gmp_int& result, const gmp_int& v) -{ - mpz_ior(result.data(), result.data(), v.data()); -} - -inline void eval_bitwise_xor(gmp_int& result, const gmp_int& v) -{ - mpz_xor(result.data(), result.data(), v.data()); -} - -inline void eval_add(gmp_int& t, const gmp_int& p, const gmp_int& o) -{ - mpz_add(t.data(), p.data(), o.data()); -} -inline void eval_subtract(gmp_int& t, const gmp_int& p, const gmp_int& o) -{ - mpz_sub(t.data(), p.data(), o.data()); -} -inline void eval_multiply(gmp_int& t, const gmp_int& p, const gmp_int& o) -{ - mpz_mul(t.data(), p.data(), o.data()); -} -inline void eval_divide(gmp_int& t, const gmp_int& p, const gmp_int& o) -{ - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q(t.data(), p.data(), o.data()); -} -inline void eval_modulus(gmp_int& t, const gmp_int& p, const gmp_int& o) -{ - mpz_tdiv_r(t.data(), p.data(), o.data()); -} -inline void eval_add(gmp_int& t, const gmp_int& p, unsigned long i) -{ - mpz_add_ui(t.data(), p.data(), i); -} -inline void eval_subtract(gmp_int& t, const gmp_int& p, unsigned long i) -{ - mpz_sub_ui(t.data(), p.data(), i); -} -inline void eval_multiply(gmp_int& t, const gmp_int& p, unsigned long i) -{ - mpz_mul_ui(t.data(), p.data(), i); -} -inline void eval_modulus(gmp_int& t, const gmp_int& p, unsigned long i) -{ - mpz_tdiv_r_ui(t.data(), p.data(), i); -} -inline void eval_divide(gmp_int& t, const gmp_int& p, unsigned long i) -{ - if(i == 0) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q_ui(t.data(), p.data(), i); -} -inline void eval_add(gmp_int& t, const gmp_int& p, long i) -{ - if(i > 0) - mpz_add_ui(t.data(), p.data(), i); - else - mpz_sub_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -inline void eval_subtract(gmp_int& t, const gmp_int& p, long i) -{ - if(i > 0) - mpz_sub_ui(t.data(), p.data(), i); - else - mpz_add_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -inline void eval_multiply(gmp_int& t, const gmp_int& p, long i) -{ - mpz_mul_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); - if(i < 0) - mpz_neg(t.data(), t.data()); -} -inline void eval_modulus(gmp_int& t, const gmp_int& p, long i) -{ - mpz_tdiv_r_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -inline void eval_divide(gmp_int& t, const gmp_int& p, long i) -{ - if(i == 0) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); - if(i < 0) - mpz_neg(t.data(), t.data()); -} - -inline void eval_bitwise_and(gmp_int& result, const gmp_int& u, const gmp_int& v) -{ - mpz_and(result.data(), u.data(), v.data()); -} - -inline void eval_bitwise_or(gmp_int& result, const gmp_int& u, const gmp_int& v) -{ - mpz_ior(result.data(), u.data(), v.data()); -} - -inline void eval_bitwise_xor(gmp_int& result, const gmp_int& u, const gmp_int& v) -{ - mpz_xor(result.data(), u.data(), v.data()); -} - -inline void eval_complement(gmp_int& result, const gmp_int& u) -{ - mpz_com(result.data(), u.data()); -} - -inline int eval_get_sign(const gmp_int& val) -{ - return mpz_sgn(val.data()); -} -inline void eval_convert_to(unsigned long* result, const gmp_int& val) -{ - if (mpz_sgn(val.data()) < 0) - { - BOOST_THROW_EXCEPTION(std::range_error("Conversion from negative integer to an unsigned type results in undefined behaviour")); - } - else if(0 == mpz_fits_ulong_p(val.data())) - { - *result = (std::numeric_limits<unsigned long>::max)(); - } - else - *result = (unsigned long)mpz_get_ui(val.data()); -} -inline void eval_convert_to(long* result, const gmp_int& val) -{ - if(0 == mpz_fits_slong_p(val.data())) - { - *result = mpz_sgn(val.data()) < 0 ? (std::numeric_limits<long>::min)() : (std::numeric_limits<long>::max)(); - } - else - *result = (signed long)mpz_get_si(val.data()); -} -inline void eval_convert_to(double* result, const gmp_int& val) -{ - *result = mpz_get_d(val.data()); -} - -inline void eval_abs(gmp_int& result, const gmp_int& val) -{ - mpz_abs(result.data(), val.data()); -} - -inline void eval_gcd(gmp_int& result, const gmp_int& a, const gmp_int& b) -{ - mpz_gcd(result.data(), a.data(), b.data()); -} -inline void eval_lcm(gmp_int& result, const gmp_int& a, const gmp_int& b) -{ - mpz_lcm(result.data(), a.data(), b.data()); -} -template <class I> -inline typename enable_if_c<(is_unsigned<I>::value && (sizeof(I) <= sizeof(unsigned long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b) -{ - mpz_gcd_ui(result.data(), a.data(), b); -} -template <class I> -inline typename enable_if_c<(is_unsigned<I>::value && (sizeof(I) <= sizeof(unsigned long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b) -{ - mpz_lcm_ui(result.data(), a.data(), b); -} -template <class I> -inline typename enable_if_c<(is_signed<I>::value && (sizeof(I) <= sizeof(long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b) -{ - mpz_gcd_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b)); -} -template <class I> -inline typename enable_if_c<is_signed<I>::value && ((sizeof(I) <= sizeof(long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b) -{ - mpz_lcm_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b)); -} - -inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x) -{ - mpz_sqrtrem(s.data(), r.data(), x.data()); -} - -inline unsigned eval_lsb(const gmp_int& val) -{ - int c = eval_get_sign(val); - if(c == 0) - { - BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand.")); - } - if(c < 0) - { - BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - return static_cast<unsigned>(mpz_scan1(val.data(), 0)); -} - -inline unsigned eval_msb(const gmp_int& val) -{ - int c = eval_get_sign(val); - if(c == 0) - { - BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand.")); - } - if(c < 0) - { - BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - return static_cast<unsigned>(mpz_sizeinbase(val.data(), 2) - 1); -} - -inline bool eval_bit_test(const gmp_int& val, unsigned index) -{ - return mpz_tstbit(val.data(), index) ? true : false; -} - -inline void eval_bit_set(gmp_int& val, unsigned index) -{ - mpz_setbit(val.data(), index); -} - -inline void eval_bit_unset(gmp_int& val, unsigned index) -{ - mpz_clrbit(val.data(), index); -} - -inline void eval_bit_flip(gmp_int& val, unsigned index) -{ - mpz_combit(val.data(), index); -} - -inline void eval_qr(const gmp_int& x, const gmp_int& y, - gmp_int& q, gmp_int& r) -{ - mpz_tdiv_qr(q.data(), r.data(), x.data(), y.data()); -} - -template <class Integer> -inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val) -{ -#if defined(__MPIR_VERSION) && (__MPIR_VERSION >= 3) - if((sizeof(Integer) <= sizeof(mpir_ui)) || (val <= (std::numeric_limits<mpir_ui>::max)())) -#else - if((sizeof(Integer) <= sizeof(long)) || (val <= (std::numeric_limits<unsigned long>::max)())) -#endif - { - return static_cast<Integer>(mpz_tdiv_ui(x.data(), val)); - } - else - { - return default_ops::eval_integer_modulus(x, val); - } -} -template <class Integer> -inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val) -{ - return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); -} -inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m) -{ - if(eval_get_sign(p) < 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } - mpz_powm(result.data(), base.data(), p.data(), m.data()); -} - -template <class Integer> -inline typename enable_if< - mpl::and_< - is_unsigned<Integer>, - mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)> - > ->::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m) -{ - mpz_powm_ui(result.data(), base.data(), p, m.data()); -} -template <class Integer> -inline typename enable_if< - mpl::and_< - is_signed<Integer>, - mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)> - > ->::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m) -{ - if(p < 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } - mpz_powm_ui(result.data(), base.data(), p, m.data()); -} - -inline std::size_t hash_value(const gmp_int& val) -{ - // We should really use mpz_limbs_read here, but that's unsupported on older versions: - std::size_t result = 0; - for(int i = 0; i < std::abs(val.data()[0]._mp_size); ++i) - boost::hash_combine(result, val.data()[0]._mp_d[i]); - boost::hash_combine(result, val.data()[0]._mp_size); - return result; -} - -struct gmp_rational; -void eval_add(gmp_rational& t, const gmp_rational& o); - -struct gmp_rational -{ -#ifdef BOOST_HAS_LONG_LONG - typedef mpl::list<long, boost::long_long_type> signed_types; - typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; -#else - typedef mpl::list<long> signed_types; - typedef mpl::list<unsigned long> unsigned_types; -#endif - typedef mpl::list<double, long double> float_types; - - gmp_rational() - { - mpq_init(this->m_data); - } - gmp_rational(const gmp_rational& o) - { - mpq_init(m_data); - if(o.m_data[0]._mp_num._mp_d) - mpq_set(m_data, o.m_data); - } - gmp_rational(const gmp_int& o) - { - mpq_init(m_data); - mpq_set_z(m_data, o.data()); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_rational(gmp_rational&& o) BOOST_NOEXCEPT - { - m_data[0] = o.m_data[0]; - o.m_data[0]._mp_num._mp_d = 0; - o.m_data[0]._mp_den._mp_d = 0; - } -#endif - gmp_rational(const mpq_t o) - { - mpq_init(m_data); - mpq_set(m_data, o); - } - gmp_rational(const mpz_t o) - { - mpq_init(m_data); - mpq_set_z(m_data, o); - } - gmp_rational& operator = (const gmp_rational& o) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - mpq_set(m_data, o.m_data); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - gmp_rational& operator = (gmp_rational&& o) BOOST_NOEXCEPT - { - mpq_swap(m_data, o.m_data); - return *this; - } -#endif -#ifdef BOOST_HAS_LONG_LONG -#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) - gmp_rational& operator = (boost::ulong_long_type i) - { - *this = static_cast<unsigned long>(i); - return *this; - } -#else - gmp_rational& operator = (boost::ulong_long_type i) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - gmp_int zi; - zi = i; - mpq_set_z(m_data, zi.data()); - return *this; - } - gmp_rational& operator = (boost::long_long_type i) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - bool neg = i < 0; - *this = boost::multiprecision::detail::unsigned_abs(i); - if(neg) - mpq_neg(m_data, m_data); - return *this; - } -#endif -#endif - gmp_rational& operator = (unsigned long i) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - mpq_set_ui(m_data, i, 1); - return *this; - } - gmp_rational& operator = (long i) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - mpq_set_si(m_data, i, 1); - return *this; - } - gmp_rational& operator = (double d) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - mpq_set_d(m_data, d); - return *this; - } - gmp_rational& operator = (long double a) - { - using std::frexp; - using std::ldexp; - using std::floor; - using default_ops::eval_add; - using default_ops::eval_subtract; - - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - - if (a == 0) { - mpq_set_si(m_data, 0, 1); - return *this; - } - - if (a == 1) { - mpq_set_si(m_data, 1, 1); - return *this; - } - - BOOST_ASSERT(!(boost::math::isinf)(a)); - BOOST_ASSERT(!(boost::math::isnan)(a)); - - int e; - long double f, term; - mpq_set_ui(m_data, 0, 1); - mpq_set_ui(m_data, 0u, 1); - gmp_rational t; - - f = frexp(a, &e); - - static const int shift = std::numeric_limits<int>::digits - 1; - - while(f) - { - // extract int sized bits from f: - f = ldexp(f, shift); - term = floor(f); - e -= shift; - mpq_mul_2exp(m_data, m_data, shift); - t = static_cast<long>(term); - eval_add(*this, t); - f -= term; - } - if(e > 0) - mpq_mul_2exp(m_data, m_data, e); - else if(e < 0) - mpq_div_2exp(m_data, m_data, -e); - return *this; - } - gmp_rational& operator = (const char* s) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - if(0 != mpq_set_str(m_data, s, 10)) - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid rational number."))); - return *this; - } - gmp_rational& operator=(const gmp_int& o) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - mpq_set_z(m_data, o.data()); - return *this; - } - gmp_rational& operator=(const mpq_t o) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - mpq_set(m_data, o); - return *this; - } - gmp_rational& operator=(const mpz_t o) - { - if(m_data[0]._mp_den._mp_d == 0) - mpq_init(m_data); - mpq_set_z(m_data, o); - return *this; - } - void swap(gmp_rational& o) - { - mpq_swap(m_data, o.m_data); - } - std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags /*f*/)const - { - BOOST_ASSERT(m_data[0]._mp_num._mp_d); - // TODO make a better job of this including handling of f!! - void *(*alloc_func_ptr) (size_t); - void *(*realloc_func_ptr) (void *, size_t, size_t); - void (*free_func_ptr) (void *, size_t); - const char* ps = mpq_get_str (0, 10, m_data); - std::string s = ps; - mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr); - (*free_func_ptr)((void*)ps, std::strlen(ps) + 1); - return s; - } - ~gmp_rational() - { - if(m_data[0]._mp_num._mp_d || m_data[0]._mp_den._mp_d) - mpq_clear(m_data); - } - void negate() - { - BOOST_ASSERT(m_data[0]._mp_num._mp_d); - mpq_neg(m_data, m_data); - } - int compare(const gmp_rational& o)const - { - BOOST_ASSERT(m_data[0]._mp_num._mp_d && o.m_data[0]._mp_num._mp_d); - return mpq_cmp(m_data, o.m_data); - } - template <class V> - int compare(V v)const - { - gmp_rational d; - d = v; - return compare(d); - } - int compare(unsigned long v)const - { - BOOST_ASSERT(m_data[0]._mp_num._mp_d); - return mpq_cmp_ui(m_data, v, 1); - } - int compare(long v)const - { - BOOST_ASSERT(m_data[0]._mp_num._mp_d); - return mpq_cmp_si(m_data, v, 1); - } - mpq_t& data() - { - BOOST_ASSERT(m_data[0]._mp_num._mp_d); - return m_data; - } - const mpq_t& data()const - { - BOOST_ASSERT(m_data[0]._mp_num._mp_d); - return m_data; - } -protected: - mpq_t m_data; -}; - -inline bool eval_is_zero(const gmp_rational& val) -{ - return mpq_sgn(val.data()) == 0; -} -template <class T> -inline bool eval_eq(gmp_rational& a, const T& b) -{ - return a.compare(b) == 0; -} -template <class T> -inline bool eval_lt(gmp_rational& a, const T& b) -{ - return a.compare(b) < 0; -} -template <class T> -inline bool eval_gt(gmp_rational& a, const T& b) -{ - return a.compare(b) > 0; -} - -inline void eval_add(gmp_rational& t, const gmp_rational& o) -{ - mpq_add(t.data(), t.data(), o.data()); -} -inline void eval_subtract(gmp_rational& t, const gmp_rational& o) -{ - mpq_sub(t.data(), t.data(), o.data()); -} -inline void eval_multiply(gmp_rational& t, const gmp_rational& o) -{ - mpq_mul(t.data(), t.data(), o.data()); -} -inline void eval_divide(gmp_rational& t, const gmp_rational& o) -{ - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpq_div(t.data(), t.data(), o.data()); -} -inline void eval_add(gmp_rational& t, const gmp_rational& p, const gmp_rational& o) -{ - mpq_add(t.data(), p.data(), o.data()); -} -inline void eval_subtract(gmp_rational& t, const gmp_rational& p, const gmp_rational& o) -{ - mpq_sub(t.data(), p.data(), o.data()); -} -inline void eval_multiply(gmp_rational& t, const gmp_rational& p, const gmp_rational& o) -{ - mpq_mul(t.data(), p.data(), o.data()); -} -inline void eval_divide(gmp_rational& t, const gmp_rational& p, const gmp_rational& o) -{ - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpq_div(t.data(), p.data(), o.data()); -} - -inline int eval_get_sign(const gmp_rational& val) -{ - return mpq_sgn(val.data()); -} -inline void eval_convert_to(double* result, const gmp_rational& val) -{ - // - // This does not round correctly: - // - //*result = mpq_get_d(val.data()); - // - // This does: - // - boost::multiprecision::detail::generic_convert_rational_to_float(*result, val); -} - -inline void eval_convert_to(long* result, const gmp_rational& val) -{ - double r; - eval_convert_to(&r, val); - *result = static_cast<long>(r); -} - -inline void eval_convert_to(unsigned long* result, const gmp_rational& val) -{ - double r; - eval_convert_to(&r, val); - *result = static_cast<long>(r); -} - -inline void eval_abs(gmp_rational& result, const gmp_rational& val) -{ - mpq_abs(result.data(), val.data()); -} - -inline void assign_components(gmp_rational& result, unsigned long v1, unsigned long v2) -{ - mpq_set_ui(result.data(), v1, v2); - mpq_canonicalize(result.data()); -} -inline void assign_components(gmp_rational& result, long v1, long v2) -{ - mpq_set_si(result.data(), v1, v2); - mpq_canonicalize(result.data()); -} -inline void assign_components(gmp_rational& result, gmp_int const& v1, gmp_int const& v2) -{ - mpz_set(mpq_numref(result.data()), v1.data()); - mpz_set(mpq_denref(result.data()), v2.data()); - mpq_canonicalize(result.data()); -} - -inline std::size_t hash_value(const gmp_rational& val) -{ - std::size_t result = 0; - for(int i = 0; i < std::abs(val.data()[0]._mp_num._mp_size); ++i) - boost::hash_combine(result, val.data()[0]._mp_num._mp_d[i]); - for(int i = 0; i < std::abs(val.data()[0]._mp_den._mp_size); ++i) - boost::hash_combine(result, val.data()[0]._mp_den._mp_d[i]); - boost::hash_combine(result, val.data()[0]._mp_num._mp_size); - return result; -} - -// -// Some member functions that are dependent upon previous code go here: -// -template <unsigned Digits10> -template <unsigned D> -inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= Digits10>::type*) -{ - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision())); - mpf_set(this->m_data, o.data()); -} -template <unsigned Digits10> -template <unsigned D> -inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= Digits10>::type*) -{ - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision())); - mpf_set(this->m_data, o.data()); -} -template <unsigned Digits10> -inline gmp_float<Digits10>::gmp_float(const gmp_int& o) -{ - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision())); - mpf_set_z(this->data(), o.data()); -} -template <unsigned Digits10> -inline gmp_float<Digits10>::gmp_float(const gmp_rational& o) -{ - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision())); - mpf_set_q(this->data(), o.data()); -} -template <unsigned Digits10> -template <unsigned D> -inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_float<D>& o) -{ - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision())); - mpf_set(this->m_data, o.data()); - return *this; -} -template <unsigned Digits10> -inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_int& o) -{ - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision())); - mpf_set_z(this->data(), o.data()); - return *this; -} -template <unsigned Digits10> -inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_rational& o) -{ - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision())); - mpf_set_q(this->data(), o.data()); - return *this; -} -inline gmp_float<0>::gmp_float(const gmp_int& o) -{ - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpf_set_z(this->data(), o.data()); -} -inline gmp_float<0>::gmp_float(const gmp_rational& o) -{ - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpf_set_q(this->data(), o.data()); -} -inline gmp_float<0>& gmp_float<0>::operator=(const gmp_int& o) -{ - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision())); - mpf_set_z(this->data(), o.data()); - return *this; -} -inline gmp_float<0>& gmp_float<0>::operator=(const gmp_rational& o) -{ - if(this->m_data[0]._mp_d == 0) - mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision())); - mpf_set_q(this->data(), o.data()); - return *this; -} -inline gmp_int::gmp_int(const gmp_rational& o) -{ - mpz_init(this->m_data); - mpz_set_q(this->m_data, o.data()); -} -inline gmp_int& gmp_int::operator=(const gmp_rational& o) -{ - if(this->m_data[0]._mp_d == 0) - mpz_init(this->m_data); - mpz_set_q(this->m_data, o.data()); - return *this; -} - -} //namespace backends - -using boost::multiprecision::backends::gmp_int; -using boost::multiprecision::backends::gmp_rational; -using boost::multiprecision::backends::gmp_float; - -template <> -struct component_type<number<gmp_rational> > -{ - typedef number<gmp_int> type; -}; - -template <expression_template_option ET> -inline number<gmp_int, ET> numerator(const number<gmp_rational, ET>& val) -{ - number<gmp_int, ET> result; - mpz_set(result.backend().data(), (mpq_numref(val.backend().data()))); - return result; -} -template <expression_template_option ET> -inline number<gmp_int, ET> denominator(const number<gmp_rational, ET>& val) -{ - number<gmp_int, ET> result; - mpz_set(result.backend().data(), (mpq_denref(val.backend().data()))); - return result; -} - -namespace detail{ - -#ifdef BOOST_NO_SFINAE_EXPR - -template<> -struct is_explicitly_convertible<canonical<mpf_t, gmp_int>::type, gmp_int> : public mpl::true_ {}; -template<> -struct is_explicitly_convertible<canonical<mpq_t, gmp_int>::type, gmp_int> : public mpl::true_ {}; -template<unsigned Digits10> -struct is_explicitly_convertible<gmp_float<Digits10>, gmp_int> : public mpl::true_ {}; -template<> -struct is_explicitly_convertible<gmp_rational, gmp_int> : public mpl::true_ {}; -template<unsigned D1, unsigned D2> -struct is_explicitly_convertible<gmp_float<D1>, gmp_float<D2> > : public mpl::true_ {}; - -#endif - -template <> -struct digits2<number<gmp_float<0>, et_on> > -{ - static long value() - { - return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision()); - } -}; - -template <> -struct digits2<number<gmp_float<0>, et_off> > -{ - static long value() - { - return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision()); - } -}; - -template <> -struct digits2<number<debug_adaptor<gmp_float<0> >, et_on> > -{ - static long value() - { - return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision()); - } -}; - -template <> -struct digits2<number<debug_adaptor<gmp_float<0> >, et_off> > -{ - static long value() - { - return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision()); - } -}; - -} - -template<> -struct number_category<detail::canonical<mpz_t, gmp_int>::type> : public mpl::int_<number_kind_integer>{}; -template<> -struct number_category<detail::canonical<mpq_t, gmp_rational>::type> : public mpl::int_<number_kind_rational>{}; -template<> -struct number_category<detail::canonical<mpf_t, gmp_float<0> >::type> : public mpl::int_<number_kind_floating_point>{}; - - -typedef number<gmp_float<50> > mpf_float_50; -typedef number<gmp_float<100> > mpf_float_100; -typedef number<gmp_float<500> > mpf_float_500; -typedef number<gmp_float<1000> > mpf_float_1000; -typedef number<gmp_float<0> > mpf_float; -typedef number<gmp_int > mpz_int; -typedef number<gmp_rational > mpq_rational; - -} // namespace multiprecision - -namespace math { namespace tools{ - - template <> - inline int digits<boost::multiprecision::mpf_float>() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif - { - return multiprecision::detail::digits10_2_2(boost::multiprecision::mpf_float::default_precision()); - } - template <> - inline int digits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif - { - return multiprecision::detail::digits10_2_2(boost::multiprecision::mpf_float::default_precision()); - } - - template <> - inline boost::multiprecision::mpf_float - max_value<boost::multiprecision::mpf_float>() - { - boost::multiprecision::mpf_float result(0.5); - mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1); - return result; - } - - template <> - inline boost::multiprecision::mpf_float - min_value<boost::multiprecision::mpf_float>() - { - boost::multiprecision::mpf_float result(0.5); - mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::min)() / 64 + 1); - return result; - } - - template <> - inline boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> - max_value<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >() - { - boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> result(0.5); - mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1); - return result; - } - - template <> - inline boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> - min_value<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >() - { - boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> result(0.5); - mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1); - return result; - } - - template <> - inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif - { - return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >::default_precision()); - } - template <> - inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif - { - return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >::default_precision()); - } - - template <> - inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > - max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >() - { - return max_value<boost::multiprecision::mpf_float>().backend(); - } - - template <> - inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > - min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >() - { - return min_value<boost::multiprecision::mpf_float>().backend(); - } - - template <> - inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> - max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >() - { - return max_value<boost::multiprecision::mpf_float>().backend(); - } - - template <> - inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> - min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >() - { - return min_value<boost::multiprecision::mpf_float>().backend(); - } - - -}} // namespaces math::tools - - -} // namespace boost - -namespace std{ - -// -// numeric_limits [partial] specializations for the types declared in this header: -// -template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - // - // min and max values chosen so as to not cause segfaults when calling - // mpf_get_str on 64-bit Linux builds. Possibly we could use larger - // exponent values elsewhere. - // - static number_type (min)() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1); - } - return value.second; - } - static number_type (max)() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpf_mul_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1); - } - return value.second; - } - BOOST_STATIC_CONSTEXPR number_type lowest() - { - return -(max)(); - } - BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301L ? 2 : 1)); - BOOST_STATIC_CONSTEXPR int digits10 = Digits10; - // Have to allow for a possible extra limb inside the gmp data structure: - BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 3 + ((GMP_LIMB_BITS * 301L) / 1000L); - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR int radix = 2; - static number_type epsilon() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1); - } - return value.second; - } - // What value should this be???? - static number_type round_error() - { - // returns epsilon/2 - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - } - return value.second; - } - BOOST_STATIC_CONSTEXPR long min_exponent = LONG_MIN; - BOOST_STATIC_CONSTEXPR long min_exponent10 = (LONG_MIN / 1000) * 301L; - BOOST_STATIC_CONSTEXPR long max_exponent = LONG_MAX; - BOOST_STATIC_CONSTEXPR long max_exponent10 = (LONG_MAX / 1000) * 301L; - BOOST_STATIC_CONSTEXPR bool has_infinity = false; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - BOOST_STATIC_CONSTEXPR number_type infinity() { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type quiet_NaN() { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = true; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = true; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate; - -private: - struct data_initializer - { - data_initializer() - { - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::epsilon(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::round_error(); - (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::min)(); - (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::max)(); - } - void do_nothing()const{} - }; - static const data_initializer initializer; -}; - -template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::initializer; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits10; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_digits10; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_signed; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_integer; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_exact; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::radix; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent10; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent10; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_infinity; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_quiet_NaN; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_signaling_NaN; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm_loss; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_iec559; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_bounded; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_modulo; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::traps; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::tinyness_before; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::round_style; - -#endif - -template<boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = false; - static number_type (min)() { return number_type(); } - static number_type (max)() { return number_type(); } - static number_type lowest() { return number_type(); } - BOOST_STATIC_CONSTEXPR int digits = 0; - BOOST_STATIC_CONSTEXPR int digits10 = 0; - BOOST_STATIC_CONSTEXPR int max_digits10 = 0; - BOOST_STATIC_CONSTEXPR bool is_signed = false; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR int radix = 0; - static number_type epsilon() { return number_type(); } - static number_type round_error() { return number_type(); } - BOOST_STATIC_CONSTEXPR int min_exponent = 0; - BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; - BOOST_STATIC_CONSTEXPR int max_exponent = 0; - BOOST_STATIC_CONSTEXPR int max_exponent10 = 0; - BOOST_STATIC_CONSTEXPR bool has_infinity = false; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() { return number_type(); } - static number_type quiet_NaN() { return number_type(); } - static number_type signaling_NaN() { return number_type(); } - static number_type denorm_min() { return number_type(); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = false; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = false; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate; -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_signed; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_integer; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_exact; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::radix; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_infinity; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_quiet_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_signaling_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm_loss; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_iec559; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_bounded; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_modulo; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::traps; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::tinyness_before; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::round_style; - -#endif - -template<boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - // - // Largest and smallest numbers are bounded only by available memory, set - // to zero: - // - static number_type (min)() - { - return number_type(); - } - static number_type (max)() - { - return number_type(); - } - static number_type lowest() { return (min)(); } - BOOST_STATIC_CONSTEXPR int digits = INT_MAX; - BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L; - BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3; - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = true; - BOOST_STATIC_CONSTEXPR bool is_exact = true; - BOOST_STATIC_CONSTEXPR int radix = 2; - static number_type epsilon() { return number_type(); } - static number_type round_error() { return number_type(); } - BOOST_STATIC_CONSTEXPR int min_exponent = 0; - BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; - BOOST_STATIC_CONSTEXPR int max_exponent = 0; - BOOST_STATIC_CONSTEXPR int max_exponent10 = 0; - BOOST_STATIC_CONSTEXPR bool has_infinity = false; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() { return number_type(); } - static number_type quiet_NaN() { return number_type(); } - static number_type signaling_NaN() { return number_type(); } - static number_type denorm_min() { return number_type(); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = false; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = false; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero; -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_signed; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_integer; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_exact; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::radix; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_infinity; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_quiet_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_signaling_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm_loss; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_iec559; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_bounded; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_modulo; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::traps; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::tinyness_before; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::round_style; - -#endif - -template<boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - // - // Largest and smallest numbers are bounded only by available memory, set - // to zero: - // - static number_type (min)() - { - return number_type(); - } - static number_type (max)() - { - return number_type(); - } - static number_type lowest() { return (min)(); } - // Digits are unbounded, use zero for now: - BOOST_STATIC_CONSTEXPR int digits = INT_MAX; - BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L; - BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3; - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = true; - BOOST_STATIC_CONSTEXPR int radix = 2; - static number_type epsilon() { return number_type(); } - static number_type round_error() { return number_type(); } - BOOST_STATIC_CONSTEXPR int min_exponent = 0; - BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; - BOOST_STATIC_CONSTEXPR int max_exponent = 0; - BOOST_STATIC_CONSTEXPR int max_exponent10 = 0; - BOOST_STATIC_CONSTEXPR bool has_infinity = false; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() { return number_type(); } - static number_type quiet_NaN() { return number_type(); } - static number_type signaling_NaN() { return number_type(); } - static number_type denorm_min() { return number_type(); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = false; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = false; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero; -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_signed; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_integer; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_exact; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::radix; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_infinity; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_quiet_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_signaling_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm_loss; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_iec559; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_bounded; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_modulo; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::traps; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::tinyness_before; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::round_style; - -#endif - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -} // namespace std - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/integer.hpp b/contrib/restricted/boost/boost/multiprecision/integer.hpp deleted file mode 100644 index e4c8bf8b6c..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/integer.hpp +++ /dev/null @@ -1,251 +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_ - -#ifndef BOOST_MP_INTEGER_HPP -#define BOOST_MP_INTEGER_HPP - -#include <boost/multiprecision/cpp_int.hpp> -#include <boost/multiprecision/detail/bitscan.hpp> - -namespace boost{ -namespace multiprecision{ - -template <class Integer, class I2> -typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type - multiply(Integer& result, const I2& a, const I2& b) -{ - return result = static_cast<Integer>(a) * static_cast<Integer>(b); -} -template <class Integer, class I2> -typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type - add(Integer& result, const I2& a, const I2& b) -{ - return result = static_cast<Integer>(a) + static_cast<Integer>(b); -} -template <class Integer, class I2> -typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type - subtract(Integer& result, const I2& a, const I2& b) -{ - return result = static_cast<Integer>(a) - static_cast<Integer>(b); -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value>::type divide_qr(const Integer& x, const Integer& y, Integer& q, Integer& r) -{ - q = x / y; - r = x % y; -} - -template <class I1, class I2> -typename enable_if_c<is_integral<I1>::value && is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val) -{ - return static_cast<I2>(x % val); -} - -namespace detail{ -// -// Figure out the kind of integer that has twice as many bits as some builtin -// integer type I. Use a native type if we can (including types which may not -// be recognised by boost::int_t because they're larger than boost::long_long_type), -// otherwise synthesize a cpp_int to do the job. -// -template <class I> -struct double_integer -{ - static const unsigned int_t_digits = - 2 * sizeof(I) <= sizeof(boost::long_long_type) ? std::numeric_limits<I>::digits * 2 : 1; - - typedef typename mpl::if_c< - 2 * sizeof(I) <= sizeof(boost::long_long_type), - typename mpl::if_c< - is_signed<I>::value, - typename boost::int_t<int_t_digits>::least, - typename boost::uint_t<int_t_digits>::least - >::type, - typename mpl::if_c< - 2 * sizeof(I) <= sizeof(double_limb_type), - typename mpl::if_c< - is_signed<I>::value, - signed_double_limb_type, - double_limb_type - >::type, - number<cpp_int_backend<sizeof(I)*CHAR_BIT*2, sizeof(I)*CHAR_BIT*2, (is_signed<I>::value ? signed_magnitude : unsigned_magnitude), unchecked, void> > - >::type - >::type type; -}; - -} - -template <class I1, class I2, class I3> -typename enable_if_c<is_integral<I1>::value && is_unsigned<I2>::value && is_integral<I3>::value, I1>::type - powm(const I1& a, I2 b, I3 c) -{ - typedef typename detail::double_integer<I1>::type double_type; - - I1 x(1), y(a); - double_type result; - - while(b > 0) - { - if(b & 1) - { - multiply(result, x, y); - x = integer_modulus(result, c); - } - multiply(result, y, y); - y = integer_modulus(result, c); - b >>= 1; - } - return x % c; -} - -template <class I1, class I2, class I3> -inline typename enable_if_c<is_integral<I1>::value && is_signed<I2>::value && is_integral<I3>::value, I1>::type - powm(const I1& a, I2 b, I3 c) -{ - if(b < 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } - return powm(a, static_cast<typename make_unsigned<I2>::type>(b), c); -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value, unsigned>::type lsb(const Integer& val) -{ - if(val <= 0) - { - if(val == 0) - { - BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand.")); - } - else - { - BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - } - return detail::find_lsb(val); -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value, unsigned>::type msb(Integer val) -{ - if(val <= 0) - { - if(val == 0) - { - BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand.")); - } - else - { - BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - } - return detail::find_msb(val); -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value, bool>::type bit_test(const Integer& val, unsigned index) -{ - Integer mask = 1; - if(index >= sizeof(Integer) * CHAR_BIT) - return 0; - if(index) - mask <<= index; - return val & mask ? true : false; -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_set(Integer& val, unsigned index) -{ - Integer mask = 1; - if(index >= sizeof(Integer) * CHAR_BIT) - return val; - if(index) - mask <<= index; - val |= mask; - return val; -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_unset(Integer& val, unsigned index) -{ - Integer mask = 1; - if(index >= sizeof(Integer) * CHAR_BIT) - return val; - if(index) - mask <<= index; - val &= ~mask; - return val; -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_flip(Integer& val, unsigned index) -{ - Integer mask = 1; - if(index >= sizeof(Integer) * CHAR_BIT) - return val; - if(index) - mask <<= index; - val ^= mask; - return val; -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value, Integer>::type sqrt(const Integer& x, Integer& r) -{ - // - // This is slow bit-by-bit integer square root, see for example - // http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29 - // There are better methods such as http://hal.inria.fr/docs/00/07/28/54/PDF/RR-3805.pdf - // and http://hal.inria.fr/docs/00/07/21/13/PDF/RR-4475.pdf which should be implemented - // at some point. - // - Integer s = 0; - if(x == 0) - { - r = 0; - return s; - } - int g = msb(x); - if(g == 0) - { - r = 1; - return s; - } - - Integer t = 0; - r = x; - g /= 2; - bit_set(s, g); - bit_set(t, 2 * g); - r = x - t; - --g; - do - { - t = s; - t <<= g + 1; - bit_set(t, 2 * g); - if(t <= r) - { - bit_set(s, g); - r -= t; - } - --g; - } - while(g >= 0); - return s; -} - -template <class Integer> -typename enable_if_c<is_integral<Integer>::value, Integer>::type sqrt(const Integer& x) -{ - Integer r; - return sqrt(x, r); -} - -}} // namespaces - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/logged_adaptor.hpp b/contrib/restricted/boost/boost/multiprecision/logged_adaptor.hpp deleted file mode 100644 index df7ac93765..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/logged_adaptor.hpp +++ /dev/null @@ -1,571 +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_ - -#ifndef BOOST_MATH_LOGGED_ADAPTER_HPP -#define BOOST_MATH_LOGGED_ADAPTER_HPP - -#include <boost/multiprecision/traits/extract_exponent_type.hpp> -#include <boost/multiprecision/detail/integer_ops.hpp> - -namespace boost{ -namespace multiprecision{ - -template <class Backend> -inline void log_postfix_event(const Backend&, const char* /*event_description*/) -{ -} -template <class Backend, class T> -inline void log_postfix_event(const Backend&, const T&, const char* /*event_description*/) -{ -} -template <class Backend> -inline void log_prefix_event(const Backend&, const char* /*event_description*/) -{ -} -template <class Backend, class T> -inline void log_prefix_event(const Backend&, const T&, const char* /*event_description*/) -{ -} -template <class Backend, class T, class U> -inline void log_prefix_event(const Backend&, const T&, const U&, const char* /*event_description*/) -{ -} -template <class Backend, class T, class U, class V> -inline void log_prefix_event(const Backend&, const T&, const U&, const V&, const char* /*event_description*/) -{ -} - -namespace backends{ - -template <class Backend> -struct logged_adaptor -{ - typedef typename Backend::signed_types signed_types; - typedef typename Backend::unsigned_types unsigned_types; - typedef typename Backend::float_types float_types; - typedef typename extract_exponent_type< - Backend, number_category<Backend>::value>::type exponent_type; - -private: - - Backend m_value; -public: - logged_adaptor() - { - log_postfix_event(m_value, "Default construct"); - } - logged_adaptor(const logged_adaptor& o) - { - log_prefix_event(m_value, o.value(), "Copy construct"); - m_value = o.m_value; - log_postfix_event(m_value, "Copy construct"); - } - logged_adaptor& operator = (const logged_adaptor& o) - { - log_prefix_event(m_value, o.value(), "Assignment"); - m_value = o.m_value; - log_postfix_event(m_value, "Copy construct"); - return *this; - } - template <class T> - logged_adaptor(const T& i, const typename enable_if_c<is_convertible<T, Backend>::value>::type* = 0) - : m_value(i) - { - log_postfix_event(m_value, "construct from arithmetic type"); - } - template <class T> - typename enable_if_c<is_arithmetic<T>::value || is_convertible<T, Backend>::value, logged_adaptor&>::type operator = (const T& i) - { - log_prefix_event(m_value, i, "Assignment from arithmetic type"); - m_value = i; - log_postfix_event(m_value, "Assignment from arithmetic type"); - return *this; - } - logged_adaptor& operator = (const char* s) - { - log_prefix_event(m_value, s, "Assignment from string type"); - m_value = s; - log_postfix_event(m_value, "Assignment from string type"); - return *this; - } - void swap(logged_adaptor& o) - { - log_prefix_event(m_value, o.value(), "swap"); - std::swap(m_value, o.value()); - log_postfix_event(m_value, "swap"); - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f)const - { - log_prefix_event(m_value, "Conversion to string"); - std::string s = m_value.str(digits, f); - log_postfix_event(m_value, s, "Conversion to string"); - return s; - } - void negate() - { - log_prefix_event(m_value, "negate"); - m_value.negate(); - log_postfix_event(m_value, "negate"); - } - int compare(const logged_adaptor& o)const - { - log_prefix_event(m_value, o.value(), "compare"); - int r = m_value.compare(o.value()); - log_postfix_event(m_value, r, "compare"); - return r; - } - template <class T> - int compare(const T& i)const - { - log_prefix_event(m_value, i, "compare"); - int r = m_value.compare(i); - log_postfix_event(m_value, r, "compare"); - return r; - } - Backend& value() - { - return m_value; - } - const Backend& value()const - { - return m_value; - } - template <class Archive> - void serialize(Archive& ar, const unsigned int /*version*/) - { - log_prefix_event(m_value, "serialize"); - ar & m_value; - log_postfix_event(m_value, "serialize"); - } - static unsigned default_precision() BOOST_NOEXCEPT - { - return Backend::default_precision(); - } - static void default_precision(unsigned v) BOOST_NOEXCEPT - { - Backend::default_precision(v); - } - unsigned precision()const BOOST_NOEXCEPT - { - return value().precision(); - } - void precision(unsigned digits10) BOOST_NOEXCEPT - { - value().precision(digits10); - } -}; - -template <class T> -inline const T& unwrap_logged_type(const T& a) { return a; } -template <class Backend> -inline const Backend& unwrap_logged_type(const logged_adaptor<Backend>& a) { return a.value(); } - -#define NON_MEMBER_OP1(name, str) \ - template <class Backend>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), str);\ - BOOST_JOIN(eval_, name)(result.value());\ - log_postfix_event(result.value(), str);\ - } - -#define NON_MEMBER_OP2(name, str) \ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a));\ - log_postfix_event(result.value(), str);\ - } - -#define NON_MEMBER_OP3(name, str) \ - template <class Backend, class T, class U>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const U& b)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const logged_adaptor<Backend>& b)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\ - log_postfix_event(result.value(), str);\ - } - -#define NON_MEMBER_OP4(name, str) \ - template <class Backend, class T, class U, class V>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const U& b, const V& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b, const T& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b, const logged_adaptor<Backend>& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend, class T>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const logged_adaptor<Backend>& b, const logged_adaptor<Backend>& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b, const logged_adaptor<Backend>& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\ - log_postfix_event(result.value(), str);\ - }\ - template <class Backend, class T, class U>\ - inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b, const U& c)\ - {\ - using default_ops::BOOST_JOIN(eval_, name);\ - log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\ - BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\ - log_postfix_event(result.value(), str);\ - }\ - -NON_MEMBER_OP2(add, "+=") -NON_MEMBER_OP2(subtract, "-=") -NON_MEMBER_OP2(multiply, "*=") -NON_MEMBER_OP2(divide, "/=") - -template <class Backend, class R> -inline void eval_convert_to(R* result, const logged_adaptor<Backend>& val) -{ - using default_ops::eval_convert_to; - log_prefix_event(val.value(), "convert_to"); - eval_convert_to(result, val.value()); - log_postfix_event(val.value(), *result, "convert_to"); -} - -template <class Backend, class Exp> -inline void eval_frexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp* exp) -{ - log_prefix_event(arg.value(), "frexp"); - eval_frexp(result.value(), arg.value(), exp); - log_postfix_event(result.value(), *exp, "frexp"); -} - -template <class Backend, class Exp> -inline void eval_ldexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp) -{ - log_prefix_event(arg.value(), "ldexp"); - eval_ldexp(result.value(), arg.value(), exp); - log_postfix_event(result.value(), exp, "ldexp"); -} - -template <class Backend, class Exp> -inline void eval_scalbn(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp) -{ - log_prefix_event(arg.value(), "scalbn"); - eval_scalbn(result.value(), arg.value(), exp); - log_postfix_event(result.value(), exp, "scalbn"); -} - -template <class Backend> -inline typename Backend::exponent_type eval_ilogb(const logged_adaptor<Backend>& arg) -{ - log_prefix_event(arg.value(), "ilogb"); - typename Backend::exponent_type r = eval_ilogb(arg.value()); - log_postfix_event(arg.value(), "ilogb"); - return r; -} - -NON_MEMBER_OP2(floor, "floor") -NON_MEMBER_OP2(ceil, "ceil") -NON_MEMBER_OP2(sqrt, "sqrt") - -template <class Backend> -inline int eval_fpclassify(const logged_adaptor<Backend>& arg) -{ - using default_ops::eval_fpclassify; - log_prefix_event(arg.value(), "fpclassify"); - int r = eval_fpclassify(arg.value()); - log_postfix_event(arg.value(), r, "fpclassify"); - return r; -} - -/********************************************************************* -* -* Optional arithmetic operations come next: -* -*********************************************************************/ - -NON_MEMBER_OP3(add, "+") -NON_MEMBER_OP3(subtract, "-") -NON_MEMBER_OP3(multiply, "*") -NON_MEMBER_OP3(divide, "/") -NON_MEMBER_OP3(multiply_add, "fused-multiply-add") -NON_MEMBER_OP3(multiply_subtract, "fused-multiply-subtract") -NON_MEMBER_OP4(multiply_add, "fused-multiply-add") -NON_MEMBER_OP4(multiply_subtract, "fused-multiply-subtract") - -NON_MEMBER_OP1(increment, "increment") -NON_MEMBER_OP1(decrement, "decrement") - -/********************************************************************* -* -* Optional integer operations come next: -* -*********************************************************************/ - -NON_MEMBER_OP2(modulus, "%=") -NON_MEMBER_OP3(modulus, "%") -NON_MEMBER_OP2(bitwise_or, "|=") -NON_MEMBER_OP3(bitwise_or, "|") -NON_MEMBER_OP2(bitwise_and, "&=") -NON_MEMBER_OP3(bitwise_and, "&") -NON_MEMBER_OP2(bitwise_xor, "^=") -NON_MEMBER_OP3(bitwise_xor, "^") -NON_MEMBER_OP4(qr, "quotient-and-remainder") -NON_MEMBER_OP2(complement, "~") - -template <class Backend> -inline void eval_left_shift(logged_adaptor<Backend>& arg, std::size_t a) -{ - using default_ops::eval_left_shift; - log_prefix_event(arg.value(), a, "<<="); - eval_left_shift(arg.value(), a); - log_postfix_event(arg.value(), "<<="); -} -template <class Backend> -inline void eval_left_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, std::size_t b) -{ - using default_ops::eval_left_shift; - log_prefix_event(arg.value(), a, b, "<<"); - eval_left_shift(arg.value(), a.value(), b); - log_postfix_event(arg.value(), "<<"); -} -template <class Backend> -inline void eval_right_shift(logged_adaptor<Backend>& arg, std::size_t a) -{ - using default_ops::eval_right_shift; - log_prefix_event(arg.value(), a, ">>="); - eval_right_shift(arg.value(), a); - log_postfix_event(arg.value(), ">>="); -} -template <class Backend> -inline void eval_right_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, std::size_t b) -{ - using default_ops::eval_right_shift; - log_prefix_event(arg.value(), a, b, ">>"); - eval_right_shift(arg.value(), a.value(), b); - log_postfix_event(arg.value(), ">>"); -} - -template <class Backend, class T> -inline unsigned eval_integer_modulus(const logged_adaptor<Backend>& arg, const T& a) -{ - using default_ops::eval_integer_modulus; - log_prefix_event(arg.value(), a, "integer-modulus"); - unsigned r = eval_integer_modulus(arg.value(), a); - log_postfix_event(arg.value(), r, "integer-modulus"); - return r; -} - -template <class Backend> -inline unsigned eval_lsb(const logged_adaptor<Backend>& arg) -{ - using default_ops::eval_lsb; - log_prefix_event(arg.value(), "least-significant-bit"); - unsigned r = eval_lsb(arg.value()); - log_postfix_event(arg.value(), r, "least-significant-bit"); - return r; -} - -template <class Backend> -inline unsigned eval_msb(const logged_adaptor<Backend>& arg) -{ - using default_ops::eval_msb; - log_prefix_event(arg.value(), "most-significant-bit"); - unsigned r = eval_msb(arg.value()); - log_postfix_event(arg.value(), r, "most-significant-bit"); - return r; -} - -template <class Backend> -inline bool eval_bit_test(const logged_adaptor<Backend>& arg, unsigned a) -{ - using default_ops::eval_bit_test; - log_prefix_event(arg.value(), a, "bit-test"); - bool r = eval_bit_test(arg.value(), a); - log_postfix_event(arg.value(), r, "bit-test"); - return r; -} - -template <class Backend> -inline void eval_bit_set(const logged_adaptor<Backend>& arg, unsigned a) -{ - using default_ops::eval_bit_set; - log_prefix_event(arg.value(), a, "bit-set"); - eval_bit_set(arg.value(), a); - log_postfix_event(arg.value(), arg, "bit-set"); -} -template <class Backend> -inline void eval_bit_unset(const logged_adaptor<Backend>& arg, unsigned a) -{ - using default_ops::eval_bit_unset; - log_prefix_event(arg.value(), a, "bit-unset"); - eval_bit_unset(arg.value(), a); - log_postfix_event(arg.value(), arg, "bit-unset"); -} -template <class Backend> -inline void eval_bit_flip(const logged_adaptor<Backend>& arg, unsigned a) -{ - using default_ops::eval_bit_flip; - log_prefix_event(arg.value(), a, "bit-flip"); - eval_bit_flip(arg.value(), a); - log_postfix_event(arg.value(), arg, "bit-flip"); -} - -NON_MEMBER_OP3(gcd, "gcd") -NON_MEMBER_OP3(lcm, "lcm") -NON_MEMBER_OP4(powm, "powm") - -/********************************************************************* -* -* abs/fabs: -* -*********************************************************************/ - -NON_MEMBER_OP2(abs, "abs") -NON_MEMBER_OP2(fabs, "fabs") - -/********************************************************************* -* -* Floating point functions: -* -*********************************************************************/ - -NON_MEMBER_OP2(trunc, "trunc") -NON_MEMBER_OP2(round, "round") -NON_MEMBER_OP2(exp, "exp") -NON_MEMBER_OP2(log, "log") -NON_MEMBER_OP2(log10, "log10") -NON_MEMBER_OP2(sin, "sin") -NON_MEMBER_OP2(cos, "cos") -NON_MEMBER_OP2(tan, "tan") -NON_MEMBER_OP2(asin, "asin") -NON_MEMBER_OP2(acos, "acos") -NON_MEMBER_OP2(atan, "atan") -NON_MEMBER_OP2(sinh, "sinh") -NON_MEMBER_OP2(cosh, "cosh") -NON_MEMBER_OP2(tanh, "tanh") -NON_MEMBER_OP2(logb, "logb") -NON_MEMBER_OP3(fmod, "fmod") -NON_MEMBER_OP3(pow, "pow") -NON_MEMBER_OP3(atan2, "atan2") - -template <class Backend> -int eval_signbit(const logged_adaptor<Backend>& val) -{ - using default_ops::eval_signbit; - return eval_signbit(val.value()); -} - -template <class Backend> -std::size_t hash_value(const logged_adaptor<Backend>& val) -{ - return hash_value(val.value()); -} - -} // namespace backends - -using backends::logged_adaptor; - -template<class Backend> -struct number_category<backends::logged_adaptor<Backend> > : public number_category<Backend> {}; - -}} // namespaces - -namespace std{ - -template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates> > - : public std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > -{ - typedef std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > base_type; - typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates> number_type; -public: - static number_type (min)() BOOST_NOEXCEPT { return (base_type::min)(); } - static number_type (max)() BOOST_NOEXCEPT { return (base_type::max)(); } - static number_type lowest() BOOST_NOEXCEPT { return -(max)(); } - static number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); } - static number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; } - static number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); } - static number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); } - static number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); } - static number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); } -}; - -} // namespace std - -namespace boost{ namespace math{ - -namespace policies{ - -template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy> -struct precision< boost::multiprecision::number<boost::multiprecision::logged_adaptor<Backend>, ExpressionTemplates>, Policy> - : public precision<boost::multiprecision::number<Backend, ExpressionTemplates>, Policy> -{}; - -} // namespace policies - -}} // namespaces boost::math - -#undef NON_MEMBER_OP1 -#undef NON_MEMBER_OP2 -#undef NON_MEMBER_OP3 -#undef NON_MEMBER_OP4 - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/miller_rabin.hpp b/contrib/restricted/boost/boost/multiprecision/miller_rabin.hpp deleted file mode 100644 index 156f9b852b..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/miller_rabin.hpp +++ /dev/null @@ -1,226 +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_ - -#ifndef BOOST_MP_MR_HPP -#define BOOST_MP_MR_HPP - -#include <boost/random.hpp> -#include <boost/multiprecision/integer.hpp> - -namespace boost{ -namespace multiprecision{ -namespace detail{ - -template <class I> -bool check_small_factors(const I& n) -{ - static const boost::uint32_t small_factors1[] = { - 3u, 5u, 7u, 11u, 13u, 17u, 19u, 23u }; - static const boost::uint32_t pp1 = 223092870u; - - boost::uint32_t m1 = integer_modulus(n, pp1); - - for(unsigned i = 0; i < sizeof(small_factors1) / sizeof(small_factors1[0]); ++i) - { - BOOST_ASSERT(pp1 % small_factors1[i] == 0); - if(m1 % small_factors1[i] == 0) - return false; - } - - static const boost::uint32_t small_factors2[] = { - 29u, 31u, 37u, 41u, 43u, 47u }; - static const boost::uint32_t pp2 = 2756205443u; - - m1 = integer_modulus(n, pp2); - - for(unsigned i = 0; i < sizeof(small_factors2) / sizeof(small_factors2[0]); ++i) - { - BOOST_ASSERT(pp2 % small_factors2[i] == 0); - if(m1 % small_factors2[i] == 0) - return false; - } - - static const boost::uint32_t small_factors3[] = { - 53u, 59u, 61u, 67u, 71u }; - static const boost::uint32_t pp3 = 907383479u; - - m1 = integer_modulus(n, pp3); - - for(unsigned i = 0; i < sizeof(small_factors3) / sizeof(small_factors3[0]); ++i) - { - BOOST_ASSERT(pp3 % small_factors3[i] == 0); - if(m1 % small_factors3[i] == 0) - return false; - } - - static const boost::uint32_t small_factors4[] = { - 73u, 79u, 83u, 89u, 97u }; - static const boost::uint32_t pp4 = 4132280413u; - - m1 = integer_modulus(n, pp4); - - for(unsigned i = 0; i < sizeof(small_factors4) / sizeof(small_factors4[0]); ++i) - { - BOOST_ASSERT(pp4 % small_factors4[i] == 0); - if(m1 % small_factors4[i] == 0) - return false; - } - - static const boost::uint32_t small_factors5[6][4] = { - { 101u, 103u, 107u, 109u }, - { 113u, 127u, 131u, 137u }, - { 139u, 149u, 151u, 157u }, - { 163u, 167u, 173u, 179u }, - { 181u, 191u, 193u, 197u }, - { 199u, 211u, 223u, 227u } - }; - static const boost::uint32_t pp5[6] = - { - 121330189u, - 113u * 127u * 131u * 137u, - 139u * 149u * 151u * 157u, - 163u * 167u * 173u * 179u, - 181u * 191u * 193u * 197u, - 199u * 211u * 223u * 227u - }; - - for(unsigned k = 0; k < sizeof(pp5) / sizeof(*pp5); ++k) - { - m1 = integer_modulus(n, pp5[k]); - - for(unsigned i = 0; i < 4; ++i) - { - BOOST_ASSERT(pp5[k] % small_factors5[k][i] == 0); - if(m1 % small_factors5[k][i] == 0) - return false; - } - } - return true; -} - -inline bool is_small_prime(unsigned n) -{ - static const unsigned char p[] = - { - 3u, 5u, 7u, 11u, 13u, 17u, 19u, 23u, 29u, 31u, - 37u, 41u, 43u, 47u, 53u, 59u, 61u, 67u, 71u, 73u, - 79u, 83u, 89u, 97u, 101u, 103u, 107u, 109u, 113u, - 127u, 131u, 137u, 139u, 149u, 151u, 157u, 163u, - 167u, 173u, 179u, 181u, 191u, 193u, 197u, 199u, - 211u, 223u, 227u - }; - for(unsigned i = 0; i < sizeof(p) / sizeof(*p); ++i) - { - if(n == p[i]) - return true; - } - return false; -} - -template <class I> -typename enable_if_c<is_convertible<I, unsigned>::value, unsigned>::type - cast_to_unsigned(const I& val) -{ - return static_cast<unsigned>(val); -} -template <class I> -typename disable_if_c<is_convertible<I, unsigned>::value, unsigned>::type - cast_to_unsigned(const I& val) -{ - return val.template convert_to<unsigned>(); -} - -} // namespace detail - -template <class I, class Engine> -typename enable_if_c<number_category<I>::value == number_kind_integer, bool>::type - miller_rabin_test(const I& n, unsigned trials, Engine& gen) -{ -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4127) -#endif - typedef I number_type; - - if (n == 2) - return true; // Trivial special case. - if(bit_test(n, 0) == 0) - return false; // n is even - if(n <= 227) - return detail::is_small_prime(detail::cast_to_unsigned(n)); - - if(!detail::check_small_factors(n)) - return false; - - number_type nm1 = n - 1; - // - // Begin with a single Fermat test - it excludes a lot of candidates: - // - number_type q(228), x, y; // We know n is greater than this, as we've excluded small factors - x = powm(q, nm1, n); - if(x != 1u) - return false; - - q = n - 1; - unsigned k = lsb(q); - q >>= k; - - // Declare our random number generator: - boost::random::uniform_int_distribution<number_type> dist(2, n - 2); - // - // Execute the trials: - // - for(unsigned i = 0; i < trials; ++i) - { - x = dist(gen); - y = powm(x, q, n); - unsigned j = 0; - while(true) - { - if(y == nm1) - break; - if(y == 1) - { - if(j == 0) - break; - return false; // test failed - } - if(++j == k) - return false; // failed - y = powm(y, 2, n); - } - } - return true; // Yeheh! probably prime. -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -} - -template <class I> -typename enable_if_c<number_category<I>::value == number_kind_integer, bool>::type - miller_rabin_test(const I& x, unsigned trials) -{ - static mt19937 gen; - return miller_rabin_test(x, trials, gen); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class Engine> -bool miller_rabin_test(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4> & n, unsigned trials, Engine& gen) -{ - typedef typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type number_type; - return miller_rabin_test(number_type(n), trials, gen); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> -bool miller_rabin_test(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4> & n, unsigned trials) -{ - typedef typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type number_type; - return miller_rabin_test(number_type(n), trials); -} - -}} // namespaces - -#endif - diff --git a/contrib/restricted/boost/boost/multiprecision/mpfi.hpp b/contrib/restricted/boost/boost/multiprecision/mpfi.hpp deleted file mode 100644 index a06e4a39d4..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/mpfi.hpp +++ /dev/null @@ -1,1797 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 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_0.txt) - -#ifndef BOOST_MATH_BN_MPFI_HPP -#define BOOST_MATH_BN_MPFI_HPP - -#include <boost/multiprecision/number.hpp> -#include <boost/math/special_functions/fpclassify.hpp> -#include <boost/cstdint.hpp> -#include <boost/multiprecision/detail/big_lanczos.hpp> -#include <boost/multiprecision/detail/digits.hpp> -#include <boost/multiprecision/mpfr.hpp> -#include <boost/multiprecision/logged_adaptor.hpp> -#include <boost/math/constants/constants.hpp> -#include <boost/functional/hash_fwd.hpp> -#include <mpfi.h> -#include <cmath> -#include <algorithm> - -#ifndef BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION -# define BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION 20 -#endif - -namespace boost{ -namespace multiprecision{ -namespace backends{ - -template <unsigned digits10> -struct mpfi_float_backend; - -} // namespace backends - -template <unsigned digits10> -struct number_category<backends::mpfi_float_backend<digits10> > : public mpl::int_<number_kind_floating_point>{}; - -struct interval_error : public std::runtime_error -{ - interval_error(const std::string& s) : std::runtime_error(s) {} -}; - -namespace backends{ - -namespace detail{ - -inline int mpfi_sgn(mpfi_srcptr p) -{ - if(mpfi_is_zero(p)) - return 0; - if(mpfi_is_strictly_pos(p)) - return 1; - if(mpfi_is_strictly_neg(p)) - return -1; - BOOST_THROW_EXCEPTION(interval_error("Sign of interval is ambiguous.")); -} - -template <unsigned digits10> -struct mpfi_float_imp; - -template <unsigned digits10> -struct mpfi_float_imp -{ -#ifdef BOOST_HAS_LONG_LONG - typedef mpl::list<long, boost::long_long_type> signed_types; - typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; -#else - typedef mpl::list<long> signed_types; - typedef mpl::list<unsigned long> unsigned_types; -#endif - typedef mpl::list<double, long double> float_types; - typedef long exponent_type; - - mpfi_float_imp() - { - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfi_set_ui(m_data, 0u); - } - mpfi_float_imp(unsigned prec) - { - mpfi_init2(m_data, prec); - mpfi_set_ui(m_data, 0u); - } - - mpfi_float_imp(const mpfi_float_imp& o) - { - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - if(o.m_data[0].left._mpfr_d) - mpfi_set(m_data, o.m_data); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfi_float_imp(mpfi_float_imp&& o) BOOST_NOEXCEPT - { - m_data[0] = o.m_data[0]; - o.m_data[0].left._mpfr_d = 0; - } -#endif - mpfi_float_imp& operator = (const mpfi_float_imp& o) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - if(o.m_data[0].left._mpfr_d) - mpfi_set(m_data, o.m_data); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfi_float_imp& operator = (mpfi_float_imp&& o) BOOST_NOEXCEPT - { - mpfi_swap(m_data, o.m_data); - return *this; - } -#endif -#ifdef BOOST_HAS_LONG_LONG -#ifdef _MPFR_H_HAVE_INTMAX_T - mpfi_float_imp& operator = (boost::ulong_long_type i) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_uj(left_data(), i, GMP_RNDD); - mpfr_set_uj(right_data(), i, GMP_RNDU); - return *this; - } - mpfi_float_imp& operator = (boost::long_long_type i) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_sj(left_data(), i, GMP_RNDD); - mpfr_set_sj(right_data(), i, GMP_RNDU); - return *this; - } -#else - mpfi_float_imp& operator = (boost::ulong_long_type i) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1u); - unsigned shift = 0; - mpfi_t t; - mpfi_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10)))); - mpfi_set_ui(m_data, 0); - while(i) - { - mpfi_set_ui(t, static_cast<unsigned long>(i & mask)); - if(shift) - mpfi_mul_2exp(t, t, shift); - mpfi_add(m_data, m_data, t); - shift += std::numeric_limits<unsigned long>::digits; - i >>= std::numeric_limits<unsigned long>::digits; - } - mpfi_clear(t); - return *this; - } - mpfi_float_imp& operator = (boost::long_long_type i) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - bool neg = i < 0; - *this = boost::multiprecision::detail::unsigned_abs(i); - if(neg) - mpfi_neg(m_data, m_data); - return *this; - } -#endif -#endif - mpfi_float_imp& operator = (unsigned long i) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfi_set_ui(m_data, i); - return *this; - } - mpfi_float_imp& operator = (long i) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfi_set_si(m_data, i); - return *this; - } - mpfi_float_imp& operator = (double d) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfi_set_d(m_data, d); - return *this; - } - mpfi_float_imp& operator = (long double a) - { - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_ld(left_data(), a, GMP_RNDD); - mpfr_set_ld(right_data(), a, GMP_RNDU); - return *this; - } - mpfi_float_imp& operator = (const char* s) - { - using default_ops::eval_fpclassify; - - if(m_data[0].left._mpfr_d == 0) - mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - - if(s && (*s == '{')) - { - mpfr_float_backend<digits10> a, b; - std::string part; - const char* p = ++s; - while(*p && (*p != ',') && (*p != '}')) - ++p; - part.assign(s + 1, p); - a = part.c_str(); - s = p; - if(*p && (*p != '}')) - { - ++p; - while(*p && (*p != ',') && (*p != '}')) - ++p; - part.assign(s + 1, p); - } - else - part.erase(); - b = part.c_str(); - - if(eval_fpclassify(a) == (int)FP_NAN) - { - mpfi_set_fr(this->data(), a.data()); - } - else if(eval_fpclassify(b) == (int)FP_NAN) - { - mpfi_set_fr(this->data(), b.data()); - } - else - { - if(a.compare(b) > 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end).")); - } - mpfi_interv_fr(m_data, a.data(), b.data()); - } - } - else if(mpfi_set_str(m_data, s, 10) != 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number."))); - } - return *this; - } - void swap(mpfi_float_imp& o) BOOST_NOEXCEPT - { - mpfi_swap(m_data, o.m_data); - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f)const - { - BOOST_ASSERT(m_data[0].left._mpfr_d); - - mpfr_float_backend<digits10> a, b; - - mpfi_get_left(a.data(), m_data); - mpfi_get_right(b.data(), m_data); - - if(a.compare(b) == 0) - return a.str(digits, f); - - return "{" + a.str(digits, f) + "," + b.str(digits, f) + "}"; - } - ~mpfi_float_imp() BOOST_NOEXCEPT - { - if(m_data[0].left._mpfr_d) - mpfi_clear(m_data); - } - void negate() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0].left._mpfr_d); - mpfi_neg(m_data, m_data); - } - int compare(const mpfi_float_imp& o)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0].left._mpfr_d && o.m_data[0].left._mpfr_d); - if(mpfr_cmp(right_data(), o.left_data()) < 0) - return -1; - if(mpfr_cmp(left_data(), o.right_data()) > 0) - return 1; - if((mpfr_cmp(left_data(), o.left_data()) == 0) && (mpfr_cmp(right_data(), o.right_data()) == 0)) - return 0; - BOOST_THROW_EXCEPTION(interval_error("Ambiguous comparison between two values.")); - return 0; - } - template <class V> - int compare(V v)const BOOST_NOEXCEPT - { - mpfi_float_imp d; - d = v; - return compare(d); - } - mpfi_t& data() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0].left._mpfr_d); - return m_data; - } - const mpfi_t& data()const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0].left._mpfr_d); - return m_data; - } - mpfr_ptr left_data() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0].left._mpfr_d); - return &(m_data[0].left); - } - mpfr_srcptr left_data()const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0].left._mpfr_d); - return &(m_data[0].left); - } - mpfr_ptr right_data() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0].left._mpfr_d); - return &(m_data[0].right); - } - mpfr_srcptr right_data()const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0].left._mpfr_d); - return &(m_data[0].right); - } -protected: - mpfi_t m_data; - static unsigned& get_default_precision() BOOST_NOEXCEPT - { - static unsigned val = BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION; - return val; - } -}; - -} // namespace detail - -template <unsigned digits10> -struct mpfi_float_backend : public detail::mpfi_float_imp<digits10> -{ - mpfi_float_backend() : detail::mpfi_float_imp<digits10>() {} - mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<digits10>(o) {} -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfi_float_backend(mpfi_float_backend&& o) : detail::mpfi_float_imp<digits10>(static_cast<detail::mpfi_float_imp<digits10>&&>(o)) {} -#endif - template <unsigned D> - mpfi_float_backend(const mpfi_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0) - : detail::mpfi_float_imp<digits10>() - { - mpfi_set(this->m_data, val.data()); - } - template <unsigned D> - explicit mpfi_float_backend(const mpfi_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0) - : detail::mpfi_float_imp<digits10>() - { - mpfi_set(this->m_data, val.data()); - } - mpfi_float_backend(const mpfi_t val) - : detail::mpfi_float_imp<digits10>() - { - mpfi_set(this->m_data, val); - } - mpfi_float_backend& operator=(const mpfi_float_backend& o) - { - *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10> const&>(o); - return *this; - } - template <unsigned D> - mpfi_float_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0) - : detail::mpfi_float_imp<digits10>() - { - mpfi_set_fr(this->m_data, val.data()); - } - template <unsigned D> - mpfi_float_backend& operator=(const mpfr_float_backend<D>& val) - { - mpfi_set_fr(this->m_data, val.data()); - return *this; - } - template <unsigned D> - explicit mpfi_float_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0) - : detail::mpfi_float_imp<digits10>() - { - mpfi_set_fr(this->m_data, val.data()); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT - { - *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10>&&>(o); - return *this; - } -#endif - template <class V> - mpfi_float_backend& operator=(const V& v) - { - *static_cast<detail::mpfi_float_imp<digits10>*>(this) = v; - return *this; - } - mpfi_float_backend& operator=(const mpfi_t val) - { - mpfi_set(this->m_data, val); - return *this; - } - // We don't change our precision here, this is a fixed precision type: - template <unsigned D> - mpfi_float_backend& operator=(const mpfi_float_backend<D>& val) - { - mpfi_set(this->m_data, val.data()); - return *this; - } -}; - -template <> -struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0> -{ - mpfi_float_backend() : detail::mpfi_float_imp<0>() {} - mpfi_float_backend(const mpfi_t val) - : detail::mpfi_float_imp<0>(mpfi_get_prec(val)) - { - mpfi_set(this->m_data, val); - } - mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<0>(o) {} -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfi_float_backend(mpfi_float_backend&& o) BOOST_NOEXCEPT : detail::mpfi_float_imp<0>(static_cast<detail::mpfi_float_imp<0>&&>(o)) {} -#endif - mpfi_float_backend(const mpfi_float_backend& o, unsigned digits10) - : detail::mpfi_float_imp<0>(digits10) - { - *this = o; - } - template <unsigned D> - mpfi_float_backend(const mpfi_float_backend<D>& val) - : detail::mpfi_float_imp<0>(mpfi_get_prec(val.data())) - { - mpfi_set(this->m_data, val.data()); - } - mpfi_float_backend& operator=(const mpfi_float_backend& o) - { - mpfi_set_prec(this->m_data, mpfi_get_prec(o.data())); - mpfi_set(this->m_data, o.data()); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT - { - *static_cast<detail::mpfi_float_imp<0>*>(this) = static_cast<detail::mpfi_float_imp<0> &&>(o); - return *this; - } -#endif - template <class V> - mpfi_float_backend& operator=(const V& v) - { - *static_cast<detail::mpfi_float_imp<0>*>(this) = v; - return *this; - } - mpfi_float_backend& operator=(const mpfi_t val) - { - mpfi_set_prec(this->m_data, mpfi_get_prec(val)); - mpfi_set(this->m_data, val); - return *this; - } - template <unsigned D> - mpfi_float_backend& operator=(const mpfi_float_backend<D>& val) - { - mpfi_set_prec(this->m_data, mpfi_get_prec(val.data())); - mpfi_set(this->m_data, val.data()); - return *this; - } - static unsigned default_precision() BOOST_NOEXCEPT - { - return get_default_precision(); - } - static void default_precision(unsigned v) BOOST_NOEXCEPT - { - get_default_precision() = v; - } - unsigned precision()const BOOST_NOEXCEPT - { - return multiprecision::detail::digits2_2_10(mpfi_get_prec(this->m_data)); - } - void precision(unsigned digits10) BOOST_NOEXCEPT - { - mpfi_set_prec(this->m_data, multiprecision::detail::digits2_2_10((digits10))); - } -}; - -template <unsigned digits10, class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) == 0; -} -template <unsigned digits10, class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) < 0; -} -template <unsigned digits10, class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) > 0; -} - -template <unsigned D1, unsigned D2> -inline void eval_add(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o) -{ - mpfi_add(result.data(), result.data(), o.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o) -{ - mpfi_sub(result.data(), result.data(), o.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o) -{ - if((void*)&result == (void*)&o) - mpfi_sqr(result.data(), o.data()); - else - mpfi_mul(result.data(), result.data(), o.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o) -{ - mpfi_div(result.data(), result.data(), o.data()); -} -template <unsigned digits10> -inline void eval_add(mpfi_float_backend<digits10>& result, unsigned long i) -{ - mpfi_add_ui(result.data(), result.data(), i); -} -template <unsigned digits10> -inline void eval_subtract(mpfi_float_backend<digits10>& result, unsigned long i) -{ - mpfi_sub_ui(result.data(), result.data(), i); -} -template <unsigned digits10> -inline void eval_multiply(mpfi_float_backend<digits10>& result, unsigned long i) -{ - mpfi_mul_ui(result.data(), result.data(), i); -} -template <unsigned digits10> -inline void eval_divide(mpfi_float_backend<digits10>& result, unsigned long i) -{ - mpfi_div_ui(result.data(), result.data(), i); -} -template <unsigned digits10> -inline void eval_add(mpfi_float_backend<digits10>& result, long i) -{ - if(i > 0) - mpfi_add_ui(result.data(), result.data(), i); - else - mpfi_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -template <unsigned digits10> -inline void eval_subtract(mpfi_float_backend<digits10>& result, long i) -{ - if(i > 0) - mpfi_sub_ui(result.data(), result.data(), i); - else - mpfi_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); -} -template <unsigned digits10> -inline void eval_multiply(mpfi_float_backend<digits10>& result, long i) -{ - mpfi_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); - if(i < 0) - mpfi_neg(result.data(), result.data()); -} -template <unsigned digits10> -inline void eval_divide(mpfi_float_backend<digits10>& result, long i) -{ - mpfi_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); - if(i < 0) - mpfi_neg(result.data(), result.data()); -} -// -// Specialised 3 arg versions of the basic operators: -// -template <unsigned D1, unsigned D2, unsigned D3> -inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y) -{ - mpfi_add(a.data(), x.data(), y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y) -{ - mpfi_add_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y) -{ - if(y < 0) - mpfi_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y)); - else - mpfi_add_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_add(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y) -{ - mpfi_add_ui(a.data(), y.data(), x); -} -template <unsigned D1, unsigned D2> -inline void eval_add(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y) -{ - if(x < 0) - { - mpfi_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data()); - mpfi_neg(a.data(), a.data()); - } - else - mpfi_add_ui(a.data(), y.data(), x); -} -template <unsigned D1, unsigned D2, unsigned D3> -inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y) -{ - mpfi_sub(a.data(), x.data(), y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y) -{ - mpfi_sub_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y) -{ - if(y < 0) - mpfi_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y)); - else - mpfi_sub_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y) -{ - mpfi_ui_sub(a.data(), x, y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_subtract(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y) -{ - if(x < 0) - { - mpfi_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x)); - mpfi_neg(a.data(), a.data()); - } - else - mpfi_ui_sub(a.data(), x, y.data()); -} - -template <unsigned D1, unsigned D2, unsigned D3> -inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y) -{ - if((void*)&x == (void*)&y) - mpfi_sqr(a.data(), x.data()); - else - mpfi_mul(a.data(), x.data(), y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y) -{ - mpfi_mul_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y) -{ - if(y < 0) - { - mpfi_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y)); - a.negate(); - } - else - mpfi_mul_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y) -{ - mpfi_mul_ui(a.data(), y.data(), x); -} -template <unsigned D1, unsigned D2> -inline void eval_multiply(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y) -{ - if(x < 0) - { - mpfi_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x)); - mpfi_neg(a.data(), a.data()); - } - else - mpfi_mul_ui(a.data(), y.data(), x); -} - -template <unsigned D1, unsigned D2, unsigned D3> -inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y) -{ - mpfi_div(a.data(), x.data(), y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y) -{ - mpfi_div_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y) -{ - if(y < 0) - { - mpfi_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y)); - a.negate(); - } - else - mpfi_div_ui(a.data(), x.data(), y); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y) -{ - mpfi_ui_div(a.data(), x, y.data()); -} -template <unsigned D1, unsigned D2> -inline void eval_divide(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y) -{ - if(x < 0) - { - mpfi_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data()); - mpfi_neg(a.data(), a.data()); - } - else - mpfi_ui_div(a.data(), x, y.data()); -} - -template <unsigned digits10> -inline bool eval_is_zero(const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT -{ - return 0 != mpfi_is_zero(val.data()); -} -template <unsigned digits10> -inline int eval_get_sign(const mpfi_float_backend<digits10>& val) -{ - return detail::mpfi_sgn(val.data()); -} - -template <unsigned digits10> -inline void eval_convert_to(unsigned long* result, const mpfi_float_backend<digits10>& val) -{ - mpfr_float_backend<digits10> t; - mpfi_mid(t.data(), val.data()); - eval_convert_to(result, t); -} -template <unsigned digits10> -inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& val) -{ - mpfr_float_backend<digits10> t; - mpfi_mid(t.data(), val.data()); - eval_convert_to(result, t); -} -#ifdef _MPFR_H_HAVE_INTMAX_T -template <unsigned digits10> -inline void eval_convert_to(boost::ulong_long_type* result, const mpfi_float_backend<digits10>& val) -{ - mpfr_float_backend<digits10> t; - mpfi_mid(t.data(), val.data()); - eval_convert_to(result, t); -} -template <unsigned digits10> -inline void eval_convert_to(boost::long_long_type* result, const mpfi_float_backend<digits10>& val) -{ - mpfr_float_backend<digits10> t; - mpfi_mid(t.data(), val.data()); - eval_convert_to(result, t); -} -#endif -template <unsigned digits10> -inline void eval_convert_to(double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT -{ - *result = mpfi_get_d(val.data()); -} -template <unsigned digits10> -inline void eval_convert_to(long double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT -{ - mpfr_float_backend<digits10> t; - mpfi_mid(t.data(), val.data()); - eval_convert_to(result, t); -} - -template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> -inline void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b) -{ - using default_ops::eval_fpclassify; - if(eval_fpclassify(a) == (int)FP_NAN) - { - mpfi_set_fr(result.data(), a.data()); - } - else if(eval_fpclassify(b) == (int)FP_NAN) - { - mpfi_set_fr(result.data(), b.data()); - } - else - { - if(a.compare(b) > 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end).")); - } - mpfi_interv_fr(result.data(), a.data(), b.data()); - } -} - -template <unsigned Digits10, class V> -inline typename enable_if_c<is_convertible<V, number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> >::value >::type - assign_components(mpfi_float_backend<Digits10>& result, const V& a, const V& b) -{ - number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> x(a), y(b); - assign_components(result, x.backend(), y.backend()); -} - -// -// Native non-member operations: -// -template <unsigned Digits10> -inline void eval_sqrt(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val) -{ - mpfi_sqrt(result.data(), val.data()); -} - -template <unsigned Digits10> -inline void eval_abs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val) -{ - mpfi_abs(result.data(), val.data()); -} - -template <unsigned Digits10> -inline void eval_fabs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val) -{ - mpfi_abs(result.data(), val.data()); -} -template <unsigned Digits10> -inline void eval_ceil(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val) -{ - mpfr_float_backend<Digits10> a, b; - mpfr_set(a.data(), val.left_data(), GMP_RNDN); - mpfr_set(b.data(), val.right_data(), GMP_RNDN); - eval_ceil(a, a); - eval_ceil(b, b); - if(a.compare(b) != 0) - { - BOOST_THROW_EXCEPTION(interval_error("Attempt to take the ceil of a value that straddles an integer boundary.")); - } - mpfi_set_fr(result.data(), a.data()); -} -template <unsigned Digits10> -inline void eval_floor(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val) -{ - mpfr_float_backend<Digits10> a, b; - mpfr_set(a.data(), val.left_data(), GMP_RNDN); - mpfr_set(b.data(), val.right_data(), GMP_RNDN); - eval_floor(a, a); - eval_floor(b, b); - if(a.compare(b) != 0) - { - BOOST_THROW_EXCEPTION(interval_error("Attempt to take the floor of a value that straddles an integer boundary.")); - } - mpfi_set_fr(result.data(), a.data()); -} -template <unsigned Digits10> -inline void eval_ldexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long e) -{ - if(e > 0) - mpfi_mul_2exp(result.data(), val.data(), e); - else if(e < 0) - mpfi_div_2exp(result.data(), val.data(), -e); - else - result = val; -} -template <unsigned Digits10> -inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, int* e) -{ - mpfr_float_backend<Digits10> t, rt; - mpfi_mid(t.data(), val.data()); - eval_frexp(rt, t, e); - eval_ldexp(result, val, -*e); -} -template <unsigned Digits10> -inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long* e) -{ - mpfr_float_backend<Digits10> t, rt; - mpfi_mid(t.data(), val.data()); - eval_frexp(rt, t, e); - eval_ldexp(result, val, -*e); -} - -template <unsigned Digits10> -inline int eval_fpclassify(const mpfi_float_backend<Digits10>& val) BOOST_NOEXCEPT -{ - return mpfi_inf_p(val.data()) ? FP_INFINITE : mpfi_nan_p(val.data()) ? FP_NAN : mpfi_is_zero(val.data()) ? FP_ZERO : FP_NORMAL; -} - -template <unsigned Digits10> -inline void eval_pow(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& b, const mpfi_float_backend<Digits10>& e) -{ - typedef typename boost::multiprecision::detail::canonical<unsigned, mpfi_float_backend<Digits10> >::type ui_type; - using default_ops::eval_get_sign; - int s = eval_get_sign(b); - if(s == 0) - { - if(eval_get_sign(e) == 0) - { - result = ui_type(1); - } - else - { - result = ui_type(0); - } - return; - } - if(s < 0) - { - if(eval_get_sign(e) < 0) - { - mpfi_float_backend<Digits10> t1, t2; - t1 = e; - t1.negate(); - eval_pow(t2, b, t1); - t1 = ui_type(1); - eval_divide(result, t1, t2); - return; - } - typename boost::multiprecision::detail::canonical<boost::uintmax_t, mpfi_float_backend<Digits10> >::type an; -#ifndef BOOST_NO_EXCEPTIONS - try - { -#endif - using default_ops::eval_convert_to; - eval_convert_to(&an, e); - if(e.compare(an) == 0) - { - mpfi_float_backend<Digits10> pb(b); - pb.negate(); - eval_pow(result, pb, e); - if(an & 1u) - result.negate(); - return; - } -#ifndef BOOST_NO_EXCEPTIONS - } - catch(const std::exception&) - { - // conversion failed, just fall through, value is not an integer. - } -#endif - result = std::numeric_limits<number<mpfi_float_backend<Digits10>, et_on> >::quiet_NaN().backend(); - return; - } - mpfi_log(result.data(), b.data()); - mpfi_mul(result.data(), result.data(), e.data()); - mpfi_exp(result.data(), result.data()); -} - -template <unsigned Digits10> -inline void eval_exp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_exp(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_exp2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_exp2(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_log(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_log(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_log10(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_log10(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_sin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_sin(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_cos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_cos(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_tan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_tan(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_asin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_asin(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_acos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_acos(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_atan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_atan(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_atan2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg1, const mpfi_float_backend<Digits10>& arg2) -{ - mpfi_atan2(result.data(), arg1.data(), arg2.data()); -} - -template <unsigned Digits10> -inline void eval_sinh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_sinh(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_cosh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_cosh(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_tanh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_tanh(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline void eval_log2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg) -{ - mpfi_log2(result.data(), arg.data()); -} - -template <unsigned Digits10> -inline std::size_t hash_value(const mpfi_float_backend<Digits10>& val) -{ - std::size_t result = 0; - std::size_t len = val.left_data()[0]._mpfr_prec / mp_bits_per_limb; - if(val.left_data()[0]._mpfr_prec % mp_bits_per_limb) - ++len; - for(std::size_t i = 0; i < len; ++i) - boost::hash_combine(result, val.left_data()[0]._mpfr_d[i]); - boost::hash_combine(result, val.left_data()[0]._mpfr_exp); - boost::hash_combine(result, val.left_data()[0]._mpfr_sign); - - len = val.right_data()[0]._mpfr_prec / mp_bits_per_limb; - if(val.right_data()[0]._mpfr_prec % mp_bits_per_limb) - ++len; - for(std::size_t i = 0; i < len; ++i) - boost::hash_combine(result, val.right_data()[0]._mpfr_d[i]); - boost::hash_combine(result, val.right_data()[0]._mpfr_exp); - boost::hash_combine(result, val.right_data()[0]._mpfr_sign); - return result; -} - -template <class To, unsigned D> -void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const mpl::int_<number_kind_integer>& to_type, const mpl::int_<number_kind_floating_point>& from_type) -{ - using boost::multiprecision::detail::generic_interconvert; - mpfr_float_backend<D> t; - mpfi_mid(t.data(), from.data()); - generic_interconvert(to, t, to_type, from_type); -} - -template <class To, unsigned D> -void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const mpl::int_<number_kind_rational>& to_type, const mpl::int_<number_kind_floating_point>& from_type) -{ - using boost::multiprecision::detail::generic_interconvert; - mpfr_float_backend<D> t; - mpfi_mid(t.data(), from.data()); - generic_interconvert(to, t, to_type, from_type); -} - -template <class To, unsigned D> -void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const mpl::int_<number_kind_floating_point>& to_type, const mpl::int_<number_kind_floating_point>& from_type) -{ - using boost::multiprecision::detail::generic_interconvert; - mpfr_float_backend<D> t; - mpfi_mid(t.data(), from.data()); - generic_interconvert(to, t, to_type, from_type); -} - -} // namespace backends - -#ifdef BOOST_NO_SFINAE_EXPR - -namespace detail{ - -template<unsigned D1, unsigned D2> -struct is_explicitly_convertible<backends::mpfi_float_backend<D1>, backends::mpfi_float_backend<D2> > : public mpl::true_ {}; - -} -#endif - -template<> -struct number_category<detail::canonical<mpfi_t, backends::mpfi_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{}; -template <unsigned Digits10> -struct is_interval_number<backends::mpfi_float_backend<Digits10> > : public mpl::true_ {}; - -using boost::multiprecision::backends::mpfi_float_backend; - -typedef number<mpfi_float_backend<50> > mpfi_float_50; -typedef number<mpfi_float_backend<100> > mpfi_float_100; -typedef number<mpfi_float_backend<500> > mpfi_float_500; -typedef number<mpfi_float_backend<1000> > mpfi_float_1000; -typedef number<mpfi_float_backend<0> > mpfi_float; - -// -// Special interval specific functions: -// -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> lower(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val) -{ - number<mpfr_float_backend<Digits10> > result; - mpfr_set(result.backend().data(), val.backend().left_data(), GMP_RNDN); - return result; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> upper(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val) -{ - number<mpfr_float_backend<Digits10> > result; - mpfr_set(result.backend().data(), val.backend().right_data(), GMP_RNDN); - return result; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> median(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val) -{ - number<mpfr_float_backend<Digits10> > result; - mpfi_mid(result.backend().data(), val.backend().data()); - return result; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> width(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val) -{ - number<mpfr_float_backend<Digits10> > result; - mpfi_diam_abs(result.backend().data(), val.backend().data()); - return result; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> intersect(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b) -{ - number<mpfi_float_backend<Digits10>, ExpressionTemplates> result; - mpfi_intersect(result.backend().data(), a.backend().data(), b.backend().data()); - return result; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> hull(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b) -{ - number<mpfi_float_backend<Digits10>, ExpressionTemplates> result; - mpfi_union(result.backend().data(), a.backend().data(), b.backend().data()); - return result; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline bool overlap(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b) -{ - return (lower(a) <= lower(b) && lower(b) <= upper(a)) || - (lower(b) <= lower(a) && lower(a) <= upper(b)); -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2> -inline bool in(const number<mpfr_float_backend<Digits10>, ExpressionTemplates1>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates2>& b) -{ - return mpfi_is_inside_fr(a.backend().data(), b.backend().data()) != 0; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a) -{ - return mpfi_has_zero(a.backend().data()) != 0; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline bool subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b) -{ - return mpfi_is_inside(a.backend().data(), b.backend().data()) != 0; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline bool proper_subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b) -{ - return mpfi_is_strictly_inside(a.backend().data(), b.backend().data()) != 0; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a) -{ - return mpfi_is_empty(a.backend().data()) != 0; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline bool singleton(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a) -{ - return mpfr_cmp(a.backend().left_data(), a.backend().right_data()) == 0; -} - -template <unsigned Digits10, expression_template_option ExpressionTemplates> -struct component_type<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > -{ - typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type; -}; - -// -// Overloaded special functions which call native mpfr routines: -// -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg) -{ - boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result; - mpfi_asinh(result.backend().data(), arg.backend().data()); - return BOOST_MP_MOVE(result); -} -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg) -{ - boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result; - mpfi_acosh(result.backend().data(), arg.backend().data()); - return BOOST_MP_MOVE(result); -} -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg) -{ - boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result; - mpfi_atanh(result.backend().data(), arg.backend().data()); - return BOOST_MP_MOVE(result); -} -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg) -{ - boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result; - mpfi_cbrt(result.backend().data(), arg.backend().data()); - return BOOST_MP_MOVE(result); -} -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg) -{ - boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result; - mpfi_expm1(result.backend().data(), arg.backend().data()); - return BOOST_MP_MOVE(result); -} -template <unsigned Digits10, expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg) -{ - boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result; - mpfi_log1p(result.backend().data(), arg.backend().data()); - return BOOST_MP_MOVE(result); -} - - -} // namespace multiprecision - -namespace math{ - -namespace tools{ - -template <> -inline int digits<boost::multiprecision::mpfi_float>() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfi_float::default_precision()); -} -template <> -inline int digits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfi_float::default_precision()); -} - -template <> -inline boost::multiprecision::mpfi_float -max_value<boost::multiprecision::mpfi_float>() -{ - boost::multiprecision::mpfi_float result(0.5); - mpfi_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax()); - //BOOST_ASSERT(mpfi_number_p(result.backend().data())); - return result; -} - -template <> -inline boost::multiprecision::mpfi_float -min_value<boost::multiprecision::mpfi_float>() -{ - boost::multiprecision::mpfi_float result(0.5); - mpfi_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin()); - //BOOST_ASSERT(mpfi_number_p(result.backend().data())); - return result; -} - -template <> -inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> -max_value<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >() -{ - boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> result(0.5); - mpfi_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax()); - //BOOST_ASSERT(mpfi_number_p(result.backend().data())); - return result; -} - -template <> -inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> -min_value<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >() -{ - boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> result(0.5); - mpfi_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin()); - //BOOST_ASSERT(mpfi_number_p(result.backend().data())); - return result; -} - -// mpfi gets used with logged_adaptor fairly often, so specialize for that use case as well: -typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_on> logged_type1; -typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_off> logged_type2; - -template <> -inline int digits<logged_type1>() -#ifdef BOOST_MATH_NOEXCEPT -BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(logged_type1::default_precision()); -} -template <> -inline int digits<logged_type2 >() -#ifdef BOOST_MATH_NOEXCEPT -BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(logged_type1::default_precision()); -} - -template <> -inline logged_type1 -max_value<logged_type1>() -{ - logged_type1 result(0.5); - mpfi_mul_2exp(result.backend().value().data(), result.backend().value().data(), mpfr_get_emax()); - //BOOST_ASSERT(mpfi_number_p(result.backend().data())); - return result; -} - -template <> -inline logged_type1 -min_value<logged_type1>() -{ - logged_type1 result(0.5); - mpfi_div_2exp(result.backend().value().data(), result.backend().value().data(), -mpfr_get_emin()); - //BOOST_ASSERT(mpfi_number_p(result.backend().data())); - return result; -} - -template <> -inline logged_type2 -max_value<logged_type2 >() -{ - logged_type2 result(0.5); - mpfi_mul_2exp(result.backend().value().data(), result.backend().value().data(), mpfr_get_emax()); - //BOOST_ASSERT(mpfi_number_p(result.backend().data())); - return result; -} - -template <> -inline logged_type2 -min_value<logged_type2 >() -{ - logged_type2 result(0.5); - mpfi_div_2exp(result.backend().value().data(), result.backend().value().data(), -mpfr_get_emin()); - //BOOST_ASSERT(mpfi_number_p(result.backend().data())); - return result; -} -} // namespace tools - -namespace constants{ namespace detail{ - -template <class T> struct constant_pi; -template <class T> struct constant_ln_two; -template <class T> struct constant_euler; -template <class T> struct constant_catalan; - -// -// Initializer: ensure all our constants are initialized prior to the first call of main: -// -template <class T> -struct mpfi_initializer -{ - struct init - { - init() - { - boost::math::constants::pi<T>(); - boost::math::constants::ln_two<T>(); - boost::math::constants::euler<T>(); - boost::math::constants::catalan<T>(); - } - void force_instantiate()const{} - }; - static const init initializer; - static void force_instantiate() - { - initializer.force_instantiate(); - } -}; - -template <class T> -const typename mpfi_initializer<T>::init mpfi_initializer<T>::initializer; - -template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - mpfi_initializer<result_type>::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - has_init = true; - mpfi_const_pi(result.backend().data()); - } - return result; - } - static inline result_type get(const mpl::int_<0>&) - { - result_type result; - mpfi_const_pi(result.backend().data()); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - mpfi_initializer<result_type>::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - has_init = true; - mpfi_const_log2(result.backend().data()); - } - return result; - } - static inline result_type get(const mpl::int_<0>&) - { - result_type result; - mpfi_const_log2(result.backend().data()); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type; - template<int N> - static inline result_type const& get(const mpl::int_<N>&) - { - mpfi_initializer<result_type>::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - has_init = true; - mpfi_const_euler(result.backend().data()); - } - return result; - } - static inline result_type get(const mpl::int_<0>&) - { - result_type result; - mpfi_const_euler(result.backend().data()); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type; - template<int N> - static inline result_type const& get(const mpl::int_<N>&) - { - mpfi_initializer<result_type>::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - has_init = true; - mpfi_const_catalan(result.backend().data()); - } - return result; - } - static inline result_type get(const mpl::int_<0>&) - { - result_type result; - mpfi_const_catalan(result.backend().data()); - return result; - } -}; - -}} // namespaces - -}} // namespaces - -namespace std{ - -// -// numeric_limits [partial] specializations for the types declared in this header: -// -template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - static number_type (min)() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 0.5; - mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin()); - } - return value.second; - } - static number_type (max)() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 0.5; - mpfi_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax()); - } - return value.second; - } - BOOST_STATIC_CONSTEXPR number_type lowest() - { - return -(max)(); - } - BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1)); - BOOST_STATIC_CONSTEXPR int digits10 = Digits10; - // Is this really correct??? - BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 3; - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR int radix = 2; - static number_type epsilon() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1); - } - return value.second; - } - // What value should this be???? - static number_type round_error() - { - // returns epsilon/2 - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), 1); - } - return value.second; - } - BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT; - BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L; - BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT; - BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L; - BOOST_STATIC_CONSTEXPR bool has_infinity = true; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - boost::multiprecision::mpfr_float_backend<Digits10> t; - mpfr_set_inf(t.data(), 1); - value.first = true; - mpfi_set_fr(value.second.backend().data(), t.data()); - } - return value.second; - } - static number_type quiet_NaN() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - boost::multiprecision::mpfr_float_backend<Digits10> t; - mpfr_set_nan(t.data()); - value.first = true; - mpfi_set_fr(value.second.backend().data(), t.data()); - } - return value.second; - } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() - { - return number_type(0); - } - BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = true; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = true; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest; - -private: - struct data_initializer - { - data_initializer() - { - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::epsilon(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::round_error(); - (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::min)(); - (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::max)(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::infinity(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::quiet_NaN(); - } - void do_nothing()const{} - }; - static const data_initializer initializer; -}; - -template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::initializer; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits10; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_digits10; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_signed; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_integer; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_exact; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::radix; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent10; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent10; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_infinity; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_quiet_NaN; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_signaling_NaN; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm_loss; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_iec559; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_bounded; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_modulo; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::traps; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::tinyness_before; -template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::round_style; - -#endif - - -template<boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = false; - static number_type (min)() { return number_type(0); } - static number_type (max)() { return number_type(0); } - static number_type lowest() { return number_type(0); } - BOOST_STATIC_CONSTEXPR int digits = 0; - BOOST_STATIC_CONSTEXPR int digits10 = 0; - BOOST_STATIC_CONSTEXPR int max_digits10 = 0; - BOOST_STATIC_CONSTEXPR bool is_signed = false; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR int radix = 0; - static number_type epsilon() { return number_type(0); } - static number_type round_error() { return number_type(0); } - BOOST_STATIC_CONSTEXPR int min_exponent = 0; - BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; - BOOST_STATIC_CONSTEXPR int max_exponent = 0; - BOOST_STATIC_CONSTEXPR int max_exponent10 = 0; - BOOST_STATIC_CONSTEXPR bool has_infinity = false; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() { return number_type(0); } - static number_type quiet_NaN() { return number_type(0); } - static number_type signaling_NaN() { return number_type(0); } - static number_type denorm_min() { return number_type(0); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = false; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = false; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero; -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_signed; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_integer; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_exact; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::radix; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_infinity; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm_loss; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_iec559; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_bounded; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_modulo; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::traps; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::tinyness_before; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::round_style; - -#endif -} // namespace std -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/mpfr.hpp b/contrib/restricted/boost/boost/multiprecision/mpfr.hpp deleted file mode 100644 index 2759a8a8de..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/mpfr.hpp +++ /dev/null @@ -1,2267 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 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_0.txt) - -#ifndef BOOST_MATH_BN_MPFR_HPP -#define BOOST_MATH_BN_MPFR_HPP - -#include <boost/multiprecision/number.hpp> -#include <boost/multiprecision/debug_adaptor.hpp> -#include <boost/multiprecision/gmp.hpp> -#include <boost/math/special_functions/fpclassify.hpp> -#include <boost/cstdint.hpp> -#include <boost/multiprecision/detail/big_lanczos.hpp> -#include <boost/multiprecision/detail/digits.hpp> -#include <mpfr.h> -#include <cmath> -#include <algorithm> - -#ifndef BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION -# define BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION 20 -#endif - -namespace boost{ -namespace multiprecision{ - -enum mpfr_allocation_type -{ - allocate_stack, - allocate_dynamic -}; - -namespace backends{ - -template <unsigned digits10, mpfr_allocation_type AllocationType = allocate_dynamic> -struct mpfr_float_backend; - -template <> -struct mpfr_float_backend<0, allocate_stack>; - -} // namespace backends - -template <unsigned digits10, mpfr_allocation_type AllocationType> -struct number_category<backends::mpfr_float_backend<digits10, AllocationType> > : public mpl::int_<number_kind_floating_point>{}; - -namespace backends{ - -namespace detail{ - -template <bool b> -struct mpfr_cleanup -{ - struct initializer - { - initializer() {} - ~initializer(){ mpfr_free_cache(); } - void force_instantiate()const {} - }; - static const initializer init; - static void force_instantiate() { init.force_instantiate(); } -}; - -template <bool b> -typename mpfr_cleanup<b>::initializer const mpfr_cleanup<b>::init; - - -template <unsigned digits10, mpfr_allocation_type AllocationType> -struct mpfr_float_imp; - -template <unsigned digits10> -struct mpfr_float_imp<digits10, allocate_dynamic> -{ -#ifdef BOOST_HAS_LONG_LONG - typedef mpl::list<long, boost::long_long_type> signed_types; - typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; -#else - typedef mpl::list<long> signed_types; - typedef mpl::list<unsigned long> unsigned_types; -#endif - typedef mpl::list<double, long double> float_types; - typedef long exponent_type; - - mpfr_float_imp() - { - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_ui(m_data, 0u, GMP_RNDN); - } - mpfr_float_imp(unsigned prec) - { - mpfr_init2(m_data, prec); - mpfr_set_ui(m_data, 0u, GMP_RNDN); - } - - mpfr_float_imp(const mpfr_float_imp& o) - { - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - if(o.m_data[0]._mpfr_d) - mpfr_set(m_data, o.m_data, GMP_RNDN); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfr_float_imp(mpfr_float_imp&& o) BOOST_NOEXCEPT - { - m_data[0] = o.m_data[0]; - o.m_data[0]._mpfr_d = 0; - } -#endif - mpfr_float_imp& operator = (const mpfr_float_imp& o) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - if(o.m_data[0]._mpfr_d) - mpfr_set(m_data, o.m_data, GMP_RNDN); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfr_float_imp& operator = (mpfr_float_imp&& o) BOOST_NOEXCEPT - { - mpfr_swap(m_data, o.m_data); - return *this; - } -#endif -#ifdef BOOST_HAS_LONG_LONG -#ifdef _MPFR_H_HAVE_INTMAX_T - mpfr_float_imp& operator = (boost::ulong_long_type i) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_uj(m_data, i, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (boost::long_long_type i) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_sj(m_data, i, GMP_RNDN); - return *this; - } -#else - mpfr_float_imp& operator = (boost::ulong_long_type i) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL); - unsigned shift = 0; - mpfr_t t; - mpfr_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10)))); - mpfr_set_ui(m_data, 0, GMP_RNDN); - while(i) - { - mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN); - if(shift) - mpfr_mul_2exp(t, t, shift, GMP_RNDN); - mpfr_add(m_data, m_data, t, GMP_RNDN); - shift += std::numeric_limits<unsigned long>::digits; - i >>= std::numeric_limits<unsigned long>::digits; - } - mpfr_clear(t); - return *this; - } - mpfr_float_imp& operator = (boost::long_long_type i) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - bool neg = i < 0; - *this = boost::multiprecision::detail::unsigned_abs(i); - if(neg) - mpfr_neg(m_data, m_data, GMP_RNDN); - return *this; - } -#endif -#endif - mpfr_float_imp& operator = (unsigned long i) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_ui(m_data, i, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (long i) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_si(m_data, i, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (double d) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_d(m_data, d, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (long double a) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - mpfr_set_ld(m_data, a, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (const char* s) - { - if(m_data[0]._mpfr_d == 0) - mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number."))); - } - return *this; - } - void swap(mpfr_float_imp& o) BOOST_NOEXCEPT - { - mpfr_swap(m_data, o.m_data); - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f)const - { - BOOST_ASSERT(m_data[0]._mpfr_d); - - bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific; - bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed; - - std::streamsize org_digits(digits); - - if(scientific && digits) - ++digits; - - std::string result; - mp_exp_t e; - if(mpfr_inf_p(m_data)) - { - if(mpfr_sgn(m_data) < 0) - result = "-inf"; - else if(f & std::ios_base::showpos) - result = "+inf"; - else - result = "inf"; - return result; - } - if(mpfr_nan_p(m_data)) - { - result = "nan"; - return result; - } - if(mpfr_zero_p(m_data)) - { - e = 0; - result = "0"; - } - else - { - char* ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN); - --e; // To match with what our formatter expects. - if(fixed && e != -1) - { - // Oops we actually need a different number of digits to what we asked for: - mpfr_free_str(ps); - digits += e + 1; - if(digits == 0) - { - // We need to get *all* the digits and then possibly round up, - // we end up with either "0" or "1" as the result. - ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN); - --e; - unsigned offset = *ps == '-' ? 1 : 0; - if(ps[offset] > '5') - { - ++e; - ps[offset] = '1'; - ps[offset + 1] = 0; - } - else if(ps[offset] == '5') - { - unsigned i = offset + 1; - bool round_up = false; - while(ps[i] != 0) - { - if(ps[i] != '0') - { - round_up = true; - break; - } - } - if(round_up) - { - ++e; - ps[offset] = '1'; - ps[offset + 1] = 0; - } - else - { - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - else - { - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - else if(digits > 0) - { - ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN); - --e; // To match with what our formatter expects. - } - else - { - ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN); - --e; - unsigned offset = *ps == '-' ? 1 : 0; - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - result = ps ? ps : "0"; - if(ps) - mpfr_free_str(ps); - } - boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data)); - return result; - } - ~mpfr_float_imp() BOOST_NOEXCEPT - { - if(m_data[0]._mpfr_d) - mpfr_clear(m_data); - detail::mpfr_cleanup<true>::force_instantiate(); - } - void negate() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mpfr_d); - mpfr_neg(m_data, m_data, GMP_RNDN); - } - template <mpfr_allocation_type AllocationType> - int compare(const mpfr_float_backend<digits10, AllocationType>& o)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d); - return mpfr_cmp(m_data, o.m_data); - } - int compare(long i)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mpfr_d); - return mpfr_cmp_si(m_data, i); - } - int compare(unsigned long i)const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mpfr_d); - return mpfr_cmp_ui(m_data, i); - } - template <class V> - int compare(V v)const BOOST_NOEXCEPT - { - mpfr_float_backend<digits10, allocate_dynamic> d; - d = v; - return compare(d); - } - mpfr_t& data() BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mpfr_d); - return m_data; - } - const mpfr_t& data()const BOOST_NOEXCEPT - { - BOOST_ASSERT(m_data[0]._mpfr_d); - return m_data; - } -protected: - mpfr_t m_data; - static unsigned& get_default_precision() BOOST_NOEXCEPT - { - static unsigned val = BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION; - return val; - } -}; - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4127) // Conditional expression is constant -#endif - -template <unsigned digits10> -struct mpfr_float_imp<digits10, allocate_stack> -{ -#ifdef BOOST_HAS_LONG_LONG - typedef mpl::list<long, boost::long_long_type> signed_types; - typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; -#else - typedef mpl::list<long> signed_types; - typedef mpl::list<unsigned long> unsigned_types; -#endif - typedef mpl::list<double, long double> float_types; - typedef long exponent_type; - - static const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u); - static const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t); - - ~mpfr_float_imp() BOOST_NOEXCEPT - { - detail::mpfr_cleanup<true>::force_instantiate(); - } - mpfr_float_imp() - { - mpfr_custom_init(m_buffer, digits2); - mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer); - mpfr_set_ui(m_data, 0u, GMP_RNDN); - } - - mpfr_float_imp(const mpfr_float_imp& o) - { - mpfr_custom_init(m_buffer, digits2); - mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer); - mpfr_set(m_data, o.m_data, GMP_RNDN); - } - mpfr_float_imp& operator = (const mpfr_float_imp& o) - { - mpfr_set(m_data, o.m_data, GMP_RNDN); - return *this; - } -#ifdef BOOST_HAS_LONG_LONG -#ifdef _MPFR_H_HAVE_INTMAX_T - mpfr_float_imp& operator = (boost::ulong_long_type i) - { - mpfr_set_uj(m_data, i, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (boost::long_long_type i) - { - mpfr_set_sj(m_data, i, GMP_RNDN); - return *this; - } -#else - mpfr_float_imp& operator = (boost::ulong_long_type i) - { - boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL); - unsigned shift = 0; - mpfr_t t; - mp_limb_t t_limbs[limb_count]; - mpfr_custom_init(t_limbs, digits2); - mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs); - mpfr_set_ui(m_data, 0, GMP_RNDN); - while(i) - { - mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN); - if(shift) - mpfr_mul_2exp(t, t, shift, GMP_RNDN); - mpfr_add(m_data, m_data, t, GMP_RNDN); - shift += std::numeric_limits<unsigned long>::digits; - i >>= std::numeric_limits<unsigned long>::digits; - } - return *this; - } - mpfr_float_imp& operator = (boost::long_long_type i) - { - bool neg = i < 0; - *this = boost::multiprecision::detail::unsigned_abs(i); - if(neg) - mpfr_neg(m_data, m_data, GMP_RNDN); - return *this; - } -#endif -#endif - mpfr_float_imp& operator = (unsigned long i) - { - mpfr_set_ui(m_data, i, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (long i) - { - mpfr_set_si(m_data, i, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (double d) - { - mpfr_set_d(m_data, d, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (long double a) - { - mpfr_set_ld(m_data, a, GMP_RNDN); - return *this; - } - mpfr_float_imp& operator = (const char* s) - { - if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number."))); - } - return *this; - } - void swap(mpfr_float_imp& o) BOOST_NOEXCEPT - { - // We have to swap by copying: - mpfr_float_imp t(*this); - *this = o; - o = t; - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f)const - { - BOOST_ASSERT(m_data[0]._mpfr_d); - - bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific; - bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed; - - std::streamsize org_digits(digits); - - if(scientific && digits) - ++digits; - - std::string result; - mp_exp_t e; - if(mpfr_inf_p(m_data)) - { - if(mpfr_sgn(m_data) < 0) - result = "-inf"; - else if(f & std::ios_base::showpos) - result = "+inf"; - else - result = "inf"; - return result; - } - if(mpfr_nan_p(m_data)) - { - result = "nan"; - return result; - } - if(mpfr_zero_p(m_data)) - { - e = 0; - result = "0"; - } - else - { - char* ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN); - --e; // To match with what our formatter expects. - if(fixed && e != -1) - { - // Oops we actually need a different number of digits to what we asked for: - mpfr_free_str(ps); - digits += e + 1; - if(digits == 0) - { - // We need to get *all* the digits and then possibly round up, - // we end up with either "0" or "1" as the result. - ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN); - --e; - unsigned offset = *ps == '-' ? 1 : 0; - if(ps[offset] > '5') - { - ++e; - ps[offset] = '1'; - ps[offset + 1] = 0; - } - else if(ps[offset] == '5') - { - unsigned i = offset + 1; - bool round_up = false; - while(ps[i] != 0) - { - if(ps[i] != '0') - { - round_up = true; - break; - } - } - if(round_up) - { - ++e; - ps[offset] = '1'; - ps[offset + 1] = 0; - } - else - { - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - else - { - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - else if(digits > 0) - { - ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN); - --e; // To match with what our formatter expects. - } - else - { - ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN); - --e; - unsigned offset = *ps == '-' ? 1 : 0; - ps[offset] = '0'; - ps[offset + 1] = 0; - } - } - result = ps ? ps : "0"; - if(ps) - mpfr_free_str(ps); - } - boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data)); - return result; - } - void negate() BOOST_NOEXCEPT - { - mpfr_neg(m_data, m_data, GMP_RNDN); - } - template <mpfr_allocation_type AllocationType> - int compare(const mpfr_float_backend<digits10, AllocationType>& o)const BOOST_NOEXCEPT - { - return mpfr_cmp(m_data, o.m_data); - } - int compare(long i)const BOOST_NOEXCEPT - { - return mpfr_cmp_si(m_data, i); - } - int compare(unsigned long i)const BOOST_NOEXCEPT - { - return mpfr_cmp_ui(m_data, i); - } - template <class V> - int compare(V v)const BOOST_NOEXCEPT - { - mpfr_float_backend<digits10, allocate_stack> d; - d = v; - return compare(d); - } - mpfr_t& data() BOOST_NOEXCEPT - { - return m_data; - } - const mpfr_t& data()const BOOST_NOEXCEPT - { - return m_data; - } -protected: - mpfr_t m_data; - mp_limb_t m_buffer[limb_count]; -}; - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -} // namespace detail - -template <unsigned digits10, mpfr_allocation_type AllocationType> -struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType> -{ - mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {} - mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {} -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o)) {} -#endif - template <unsigned D, mpfr_allocation_type AT> - mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename enable_if_c<D <= digits10>::type* = 0) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set(this->m_data, val.data(), GMP_RNDN); - } - template <unsigned D, mpfr_allocation_type AT> - explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename disable_if_c<D <= digits10>::type* = 0) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set(this->m_data, val.data(), GMP_RNDN); - } - template <unsigned D> - mpfr_float_backend(const gmp_float<D>& val, typename enable_if_c<D <= digits10>::type* = 0) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set_f(this->m_data, val.data(), GMP_RNDN); - } - template <unsigned D> - mpfr_float_backend(const gmp_float<D>& val, typename disable_if_c<D <= digits10>::type* = 0) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set_f(this->m_data, val.data(), GMP_RNDN); - } - mpfr_float_backend(const gmp_int& val) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set_z(this->m_data, val.data(), GMP_RNDN); - } - mpfr_float_backend(const gmp_rational& val) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set_q(this->m_data, val.data(), GMP_RNDN); - } - mpfr_float_backend(const mpfr_t val) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set(this->m_data, val, GMP_RNDN); - } - mpfr_float_backend(const mpf_t val) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set_f(this->m_data, val, GMP_RNDN); - } - mpfr_float_backend(const mpz_t val) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set_z(this->m_data, val, GMP_RNDN); - } - mpfr_float_backend(const mpq_t val) - : detail::mpfr_float_imp<digits10, AllocationType>() - { - mpfr_set_q(this->m_data, val, GMP_RNDN); - } - mpfr_float_backend& operator=(const mpfr_float_backend& o) - { - *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o); - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT - { - *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o); - return *this; - } -#endif - template <class V> - mpfr_float_backend& operator=(const V& v) - { - *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v; - return *this; - } - mpfr_float_backend& operator=(const mpfr_t val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpfr_set(this->m_data, val, GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const mpf_t val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpfr_set_f(this->m_data, val, GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const mpz_t val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpfr_set_z(this->m_data, val, GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const mpq_t val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpfr_set_q(this->m_data, val, GMP_RNDN); - return *this; - } - // We don't change our precision here, this is a fixed precision type: - template <unsigned D, mpfr_allocation_type AT> - mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpfr_set(this->m_data, val.data(), GMP_RNDN); - return *this; - } - template <unsigned D> - mpfr_float_backend& operator=(const gmp_float<D>& val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpfr_set_f(this->m_data, val.data(), GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const gmp_int& val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpfr_set_z(this->m_data, val.data(), GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const gmp_rational& val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); - mpfr_set_q(this->m_data, val.data(), GMP_RNDN); - return *this; - } -}; - -template <> -struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic> -{ - mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {} - mpfr_float_backend(const mpfr_t val) - : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val)) - { - mpfr_set(this->m_data, val, GMP_RNDN); - } - mpfr_float_backend(const mpf_t val) - : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val)) - { - mpfr_set_f(this->m_data, val, GMP_RNDN); - } - mpfr_float_backend(const mpz_t val) - : detail::mpfr_float_imp<0, allocate_dynamic>() - { - mpfr_set_z(this->m_data, val, GMP_RNDN); - } - mpfr_float_backend(const mpq_t val) - : detail::mpfr_float_imp<0, allocate_dynamic>() - { - mpfr_set_q(this->m_data, val, GMP_RNDN); - } - mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {} -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o)) {} -#endif - mpfr_float_backend(const mpfr_float_backend& o, unsigned digits10) - : detail::mpfr_float_imp<0, allocate_dynamic>(digits10) - { - *this = o; - } - template <unsigned D> - mpfr_float_backend(const mpfr_float_backend<D>& val) - : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val.data())) - { - mpfr_set(this->m_data, val.data(), GMP_RNDN); - } - template <unsigned D> - mpfr_float_backend(const gmp_float<D>& val) - : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val.data())) - { - mpfr_set_f(this->m_data, val.data(), GMP_RNDN); - } - mpfr_float_backend(const gmp_int& val) - : detail::mpfr_float_imp<0, allocate_dynamic>() - { - mpfr_set_z(this->m_data, val.data(), GMP_RNDN); - } - mpfr_float_backend(const gmp_rational& val) - : detail::mpfr_float_imp<0, allocate_dynamic>() - { - mpfr_set_q(this->m_data, val.data(), GMP_RNDN); - } - - mpfr_float_backend& operator=(const mpfr_float_backend& o) - { - if(this != &o) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, mpfr_get_prec(o.data())); - else - mpfr_set_prec(this->m_data, mpfr_get_prec(o.data())); - mpfr_set(this->m_data, o.data(), GMP_RNDN); - } - return *this; - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT - { - *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = static_cast<detail::mpfr_float_imp<0, allocate_dynamic> &&>(o); - return *this; - } -#endif - template <class V> - mpfr_float_backend& operator=(const V& v) - { - *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v; - return *this; - } - mpfr_float_backend& operator=(const mpfr_t val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, mpfr_get_prec(val)); - else - mpfr_set_prec(this->m_data, mpfr_get_prec(val)); - mpfr_set(this->m_data, val, GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const mpf_t val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, mpf_get_prec(val)); - else - mpfr_set_prec(this->m_data, mpf_get_prec(val)); - mpfr_set_f(this->m_data, val, GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const mpz_t val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpfr_set_z(this->m_data, val, GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const mpq_t val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpfr_set_q(this->m_data, val, GMP_RNDN); - return *this; - } - template <unsigned D> - mpfr_float_backend& operator=(const mpfr_float_backend<D>& val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, mpfr_get_prec(val.data())); - else - mpfr_set_prec(this->m_data, mpfr_get_prec(val.data())); - mpfr_set(this->m_data, val.data(), GMP_RNDN); - return *this; - } - template <unsigned D> - mpfr_float_backend& operator=(const gmp_float<D>& val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, mpf_get_prec(val.data())); - else - mpfr_set_prec(this->m_data, mpf_get_prec(val.data())); - mpfr_set_f(this->m_data, val.data(), GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const gmp_int& val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpfr_set_z(this->m_data, val.data(), GMP_RNDN); - return *this; - } - mpfr_float_backend& operator=(const gmp_rational& val) - { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - mpfr_set_q(this->m_data, val.data(), GMP_RNDN); - return *this; - } - static unsigned default_precision() BOOST_NOEXCEPT - { - return get_default_precision(); - } - static void default_precision(unsigned v) BOOST_NOEXCEPT - { - get_default_precision() = v; - } - unsigned precision()const BOOST_NOEXCEPT - { - return multiprecision::detail::digits2_2_10(mpfr_get_prec(this->m_data)); - } - void precision(unsigned digits10) BOOST_NOEXCEPT - { - mpfr_prec_round(this->m_data, multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN); - } -}; - -template <unsigned digits10, mpfr_allocation_type AllocationType, class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) == 0; -} -template <unsigned digits10, mpfr_allocation_type AllocationType, class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) < 0; -} -template <unsigned digits10, mpfr_allocation_type AllocationType, class T> -inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT -{ - return a.compare(b) > 0; -} - -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o) -{ - mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o) -{ - mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o) -{ - if((void*)&o == (void*)&result) - mpfr_sqr(result.data(), o.data(), GMP_RNDN); - else - mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o) -{ - mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i) -{ - mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i) -{ - mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i) -{ - mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i) -{ - mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i) -{ - if(i > 0) - mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN); - else - mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i) -{ - if(i > 0) - mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN); - else - mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i) -{ - mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); - if(i < 0) - mpfr_neg(result.data(), result.data(), GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i) -{ - mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); - if(i < 0) - mpfr_neg(result.data(), result.data(), GMP_RNDN); -} -// -// Specialised 3 arg versions of the basic operators: -// -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3> -inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y) -{ - mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y) -{ - mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y) -{ - if(y < 0) - mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); - else - mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y) -{ - mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y) -{ - if(x < 0) - { - mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN); - mpfr_neg(a.data(), a.data(), GMP_RNDN); - } - else - mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3> -inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y) -{ - mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y) -{ - mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y) -{ - if(y < 0) - mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); - else - mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y) -{ - mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y) -{ - if(x < 0) - { - mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN); - mpfr_neg(a.data(), a.data(), GMP_RNDN); - } - else - mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN); -} - -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3> -inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y) -{ - if((void*)&x == (void*)&y) - mpfr_sqr(a.data(), x.data(), GMP_RNDN); - else - mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y) -{ - mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y) -{ - if(y < 0) - { - mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); - a.negate(); - } - else - mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y) -{ - mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y) -{ - if(x < 0) - { - mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN); - mpfr_neg(a.data(), a.data(), GMP_RNDN); - } - else - mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN); -} - -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3> -inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y) -{ - mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y) -{ - mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y) -{ - if(y < 0) - { - mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); - a.negate(); - } - else - mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y) -{ - mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN); -} -template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y) -{ - if(x < 0) - { - mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN); - mpfr_neg(a.data(), a.data(), GMP_RNDN); - } - else - mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN); -} - -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT -{ - return 0 != mpfr_zero_p(val.data()); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT -{ - return mpfr_sgn(val.data()); -} - -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val) -{ - if(mpfr_nan_p(val.data())) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); - } - *result = mpfr_get_ui(val.data(), GMP_RNDZ); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val) -{ - if(mpfr_nan_p(val.data())) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); - } - *result = mpfr_get_si(val.data(), GMP_RNDZ); -} -#ifdef _MPFR_H_HAVE_INTMAX_T -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(boost::ulong_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val) -{ - if(mpfr_nan_p(val.data())) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); - } - *result = mpfr_get_uj(val.data(), GMP_RNDZ); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(boost::long_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val) -{ - if(mpfr_nan_p(val.data())) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); - } - *result = mpfr_get_sj(val.data(), GMP_RNDZ); -} -#endif -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(float* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT -{ - *result = mpfr_get_flt(val.data(), GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT -{ - *result = mpfr_get_d(val.data(), GMP_RNDN); -} -template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT -{ - *result = mpfr_get_ld(val.data(), GMP_RNDN); -} - -// -// Native non-member operations: -// -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val) -{ - mpfr_sqrt(result.data(), val.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val) -{ - mpfr_abs(result.data(), val.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val) -{ - mpfr_abs(result.data(), val.data(), GMP_RNDN); -} -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val) -{ - mpfr_ceil(result.data(), val.data()); -} -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val) -{ - mpfr_floor(result.data(), val.data()); -} -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val) -{ - mpfr_trunc(result.data(), val.data()); -} -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e) -{ - if(e > 0) - mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN); - else if(e < 0) - mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN); - else - result = val; -} -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e) -{ - long v; - mpfr_get_d_2exp(&v, val.data(), GMP_RNDN); - *e = v; - eval_ldexp(result, val, -v); -} -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e) -{ - mpfr_get_d_2exp(e, val.data(), GMP_RNDN); - return eval_ldexp(result, val, -*e); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) BOOST_NOEXCEPT -{ - return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL; -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e) -{ - if(mpfr_zero_p(b.data()) && mpfr_integer_p(e.data()) && (mpfr_signbit(e.data()) == 0) && mpfr_fits_ulong_p(e.data(), GMP_RNDN) && (mpfr_get_ui(e.data(), GMP_RNDN) & 1)) - { - mpfr_set(result.data(), b.data(), GMP_RNDN); - } - else - mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN); -} - -#ifdef BOOST_MSVC -// -// The enable_if usage below doesn't work with msvc - but only when -// certain other enable_if usages are defined first. It's a capricious -// and rather annoying compiler bug in other words.... -// -# define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10) && -#else -#define BOOST_MP_ENABLE_IF_WORKAROUND -#endif - -template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer> -inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type - eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e) -{ - mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer> -inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type - eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e) -{ - mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN); -} - -#undef BOOST_MP_ENABLE_IF_WORKAROUND - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_exp(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_exp2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_exp2(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_log(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_log10(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_sin(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_cos(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_tan(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_asin(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_acos(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_atan(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2) -{ - mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_sinh(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_cosh(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_tanh(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_log2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - mpfr_log2(result.data(), arg.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_modf(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg, mpfr_float_backend<Digits10, AllocateType>* pipart) -{ - if(0 == pipart) - { - mpfr_float_backend<Digits10, AllocateType> ipart; - mpfr_modf(ipart.data(), result.data(), arg.data(), GMP_RNDN); - } - else - { - mpfr_modf(pipart->data(), result.data(), arg.data(), GMP_RNDN); - } -} -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_remainder(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b) -{ - mpfr_remainder(result.data(), a.data(), b.data(), GMP_RNDN); -} -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_remquo(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, int* pi) -{ - long l; - mpfr_remquo(result.data(), &l, a.data(), b.data(), GMP_RNDN); - if(pi) *pi = l; -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_fmod(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b) -{ - mpfr_fmod(result.data(), a.data(), b.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b) -{ - mpfr_fma(result.data(), a.data(), b.data(), result.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c) -{ - mpfr_fma(result.data(), a.data(), b.data(), c.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b) -{ - mpfr_fms(result.data(), a.data(), b.data(), result.data(), GMP_RNDN); - result.negate(); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c) -{ - mpfr_fms(result.data(), a.data(), b.data(), c.data(), GMP_RNDN); -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const mpfr_float_backend<Digits10, AllocateType>& arg) -{ - return (arg.data()[0]._mpfr_sign < 0) ? 1 : 0; -} - -template <unsigned Digits10, mpfr_allocation_type AllocateType> -inline std::size_t hash_value(const mpfr_float_backend<Digits10, AllocateType>& val) -{ - std::size_t result = 0; - std::size_t len = val.data()[0]._mpfr_prec / mp_bits_per_limb; - if(val.data()[0]._mpfr_prec % mp_bits_per_limb) - ++len; - for(std::size_t i = 0; i < len; ++i) - boost::hash_combine(result, val.data()[0]._mpfr_d[i]); - boost::hash_combine(result, val.data()[0]._mpfr_exp); - boost::hash_combine(result, val.data()[0]._mpfr_sign); - return result; -} - -} // namespace backends - -#ifdef BOOST_NO_SFINAE_EXPR - -namespace detail{ - -template<unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2> -struct is_explicitly_convertible<backends::mpfr_float_backend<D1, A1>, backends::mpfr_float_backend<D2, A2> > : public mpl::true_ {}; - -} - -#endif - -template<> -struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{}; - -using boost::multiprecision::backends::mpfr_float_backend; - -typedef number<mpfr_float_backend<50> > mpfr_float_50; -typedef number<mpfr_float_backend<100> > mpfr_float_100; -typedef number<mpfr_float_backend<500> > mpfr_float_500; -typedef number<mpfr_float_backend<1000> > mpfr_float_1000; -typedef number<mpfr_float_backend<0> > mpfr_float; - -typedef number<mpfr_float_backend<50, allocate_stack> > static_mpfr_float_50; -typedef number<mpfr_float_backend<100, allocate_stack> > static_mpfr_float_100; - -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& b) -{ - return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(-a) : a; -} - -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& b) -{ - return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>(-a) : a; -} - -} // namespace multiprecision - -namespace math{ - - using boost::multiprecision::signbit; - using boost::multiprecision::copysign; - -namespace tools{ - -template <> -inline int digits<boost::multiprecision::mpfr_float>() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::default_precision()); -} -template <> -inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::default_precision()); -} - -template <> -inline boost::multiprecision::mpfr_float - max_value<boost::multiprecision::mpfr_float>() -{ - boost::multiprecision::mpfr_float result(0.5); - mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN); - BOOST_ASSERT(mpfr_number_p(result.backend().data())); - return result; -} - -template <> -inline boost::multiprecision::mpfr_float - min_value<boost::multiprecision::mpfr_float>() -{ - boost::multiprecision::mpfr_float result(0.5); - mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN); - BOOST_ASSERT(mpfr_number_p(result.backend().data())); - return result; -} - -template <> -inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> - max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >() -{ - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5); - mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN); - BOOST_ASSERT(mpfr_number_p(result.backend().data())); - return result; -} - -template <> -inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> - min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >() -{ - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5); - mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN); - BOOST_ASSERT(mpfr_number_p(result.backend().data())); - return result; -} - -template <> -inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >() -#ifdef BOOST_MATH_NOEXCEPT -BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision()); -} -template <> -inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >() -#ifdef BOOST_MATH_NOEXCEPT -BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision()); -} - -template <> -inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > -max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >() -{ - return max_value<boost::multiprecision::mpfr_float>().backend(); -} - -template <> -inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > -min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >() -{ - return min_value<boost::multiprecision::mpfr_float>().backend(); -} - -template <> -inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> -max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >() -{ - return max_value<boost::multiprecision::mpfr_float>().backend(); -} - -template <> -inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> -min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >() -{ - return min_value<boost::multiprecision::mpfr_float>().backend(); -} - -} // namespace tools - -namespace constants{ namespace detail{ - -template <class T> struct constant_pi; -template <class T> struct constant_ln_two; -template <class T> struct constant_euler; -template <class T> struct constant_catalan; - -namespace detail{ - - template <class T, int N> - struct mpfr_constant_initializer - { - static void force_instantiate() - { - init.force_instantiate(); - } - private: - struct initializer - { - initializer() - { - T::get(mpl::int_<N>()); - } - void force_instantiate()const{} - }; - static const initializer init; - }; - - template <class T, int N> - typename mpfr_constant_initializer<T, N>::initializer const mpfr_constant_initializer<T, N>::init; - -} - -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - mpfr_const_pi(result.backend().data(), GMP_RNDN); - has_init = true; - } - return result; - } - static inline const result_type get(const mpl::int_<0>&) - { - result_type result; - mpfr_const_pi(result.backend().data(), GMP_RNDN); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate(); - static result_type result; - static bool init = false; - if(!init) - { - mpfr_const_log2(result.backend().data(), GMP_RNDN); - init = true; - } - return result; - } - static inline const result_type get(const mpl::int_<0>&) - { - result_type result; - mpfr_const_log2(result.backend().data(), GMP_RNDN); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate(); - static result_type result; - static bool init = false; - if(!init) - { - mpfr_const_euler(result.backend().data(), GMP_RNDN); - init = true; - } - return result; - } - static inline const result_type get(const mpl::int_<0>&) - { - result_type result; - mpfr_const_euler(result.backend().data(), GMP_RNDN); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate(); - static result_type result; - static bool init = false; - if(!init) - { - mpfr_const_catalan(result.backend().data(), GMP_RNDN); - init = true; - } - return result; - } - static inline const result_type get(const mpl::int_<0>&) - { - result_type result; - mpfr_const_catalan(result.backend().data(), GMP_RNDN); - return result; - } -}; - -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - mpfr_const_pi(result.backend().value().data(), GMP_RNDN); - has_init = true; - } - return result; - } - static inline const result_type get(const mpl::int_<0>&) - { - result_type result; - mpfr_const_pi(result.backend().value().data(), GMP_RNDN); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate(); - static result_type result; - static bool init = false; - if(!init) - { - mpfr_const_log2(result.backend().value().data(), GMP_RNDN); - init = true; - } - return result; - } - static inline const result_type get(const mpl::int_<0>&) - { - result_type result; - mpfr_const_log2(result.backend().value().data(), GMP_RNDN); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate(); - static result_type result; - static bool init = false; - if(!init) - { - mpfr_const_euler(result.backend().value().data(), GMP_RNDN); - init = true; - } - return result; - } - static inline const result_type get(const mpl::int_<0>&) - { - result_type result; - mpfr_const_euler(result.backend().value().data(), GMP_RNDN); - return result; - } -}; -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -struct constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type; - template<int N> - static inline const result_type& get(const mpl::int_<N>&) - { - detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate(); - static result_type result; - static bool init = false; - if(!init) - { - mpfr_const_catalan(result.backend().value().data(), GMP_RNDN); - init = true; - } - return result; - } - static inline const result_type get(const mpl::int_<0>&) - { - result_type result; - mpfr_const_catalan(result.backend().value().data(), GMP_RNDN); - return result; - } -}; - -}} // namespaces - -} // namespace multiprecision - -namespace multiprecision { - // - // Overloaded special functions which call native mpfr routines: - // - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> - inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg) - { - boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result; - mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN); - return BOOST_MP_MOVE(result); - } - -} - -} // namespace boost - -namespace std{ - -// -// numeric_limits [partial] specializations for the types declared in this header: -// -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - static number_type (min)() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 0.5; - mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin(), GMP_RNDN); - } - return value.second; - } - static number_type (max)() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 0.5; - mpfr_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax(), GMP_RNDN); - } - return value.second; - } - BOOST_STATIC_CONSTEXPR number_type lowest() - { - return -(max)(); - } - BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1)); - BOOST_STATIC_CONSTEXPR int digits10 = Digits10; - // Is this really correct??? - BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 3; - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR int radix = 2; - static number_type epsilon() - { - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN); - } - return value.second; - } - // What value should this be???? - static number_type round_error() - { - // returns epsilon/2 - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), 1, GMP_RNDN); - } - return value.second; - } - BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT; - BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L; - BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT; - BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L; - BOOST_STATIC_CONSTEXPR bool has_infinity = true; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() - { - // returns epsilon/2 - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpfr_set_inf(value.second.backend().data(), 1); - } - return value.second; - } - static number_type quiet_NaN() - { - // returns epsilon/2 - initializer.do_nothing(); - static std::pair<bool, number_type> value; - if(!value.first) - { - value.first = true; - value.second = 1; - mpfr_set_nan(value.second.backend().data()); - } - return value.second; - } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() - { - return number_type(0); - } - BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = true; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = true; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest; - -private: - struct data_initializer - { - data_initializer() - { - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::epsilon(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::round_error(); - (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::min)(); - (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::max)(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::infinity(); - std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::quiet_NaN(); - } - void do_nothing()const{} - }; - static const data_initializer initializer; -}; - -template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::initializer; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before; -template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style; - -#endif - - -template<boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = false; - static number_type (min)() { return number_type(0); } - static number_type (max)() { return number_type(0); } - static number_type lowest() { return number_type(0); } - BOOST_STATIC_CONSTEXPR int digits = 0; - BOOST_STATIC_CONSTEXPR int digits10 = 0; - BOOST_STATIC_CONSTEXPR int max_digits10 = 0; - BOOST_STATIC_CONSTEXPR bool is_signed = false; - BOOST_STATIC_CONSTEXPR bool is_integer = false; - BOOST_STATIC_CONSTEXPR bool is_exact = false; - BOOST_STATIC_CONSTEXPR int radix = 0; - static number_type epsilon() { return number_type(0); } - static number_type round_error() { return number_type(0); } - BOOST_STATIC_CONSTEXPR int min_exponent = 0; - BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; - BOOST_STATIC_CONSTEXPR int max_exponent = 0; - BOOST_STATIC_CONSTEXPR int max_exponent10 = 0; - BOOST_STATIC_CONSTEXPR bool has_infinity = false; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() { return number_type(0); } - static number_type quiet_NaN() { return number_type(0); } - static number_type signaling_NaN() { return number_type(0); } - static number_type denorm_min() { return number_type(0); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = false; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = false; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero; -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style; - -#endif -} // namespace std -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/random.hpp b/contrib/restricted/boost/boost/multiprecision/random.hpp deleted file mode 100644 index c6b7d34e03..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/random.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright Jens Maurer 2006-1011 -// Copyright Steven Watanabe 2011 -// 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_ - -#ifndef BOOST_MP_RANDOM_HPP -#define BOOST_MP_RANDOM_HPP - -#if defined(__GNUC__) || defined(_MSC_VER) -# pragma message("NOTE: Use of this header (boost/multiprecision/random.hpp) is deprecated: please use the random number library headers directly.") -#endif - - -#include <boost/random.hpp> - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/tommath.hpp b/contrib/restricted/boost/boost/multiprecision/tommath.hpp deleted file mode 100644 index 86d0e8f211..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/tommath.hpp +++ /dev/null @@ -1,781 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 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_0.txt) - -#ifndef BOOST_MATH_MP_TOMMATH_BACKEND_HPP -#define BOOST_MATH_MP_TOMMATH_BACKEND_HPP - -#include <boost/multiprecision/number.hpp> -#include <boost/multiprecision/rational_adaptor.hpp> -#include <boost/multiprecision/detail/integer_ops.hpp> -#include <boost/math/special_functions/fpclassify.hpp> -#include <boost/cstdint.hpp> -#include <boost/scoped_array.hpp> -#include <boost/functional/hash_fwd.hpp> -#include <tommath.h> -#include <cmath> -#include <limits> -#include <climits> - -namespace boost{ namespace multiprecision{ namespace backends{ - -namespace detail{ - -inline void check_tommath_result(unsigned v) -{ - if(v != MP_OKAY) - { - BOOST_THROW_EXCEPTION(std::runtime_error(mp_error_to_string(v))); - } -} - -} - -struct tommath_int; - -void eval_multiply(tommath_int& t, const tommath_int& o); -void eval_add(tommath_int& t, const tommath_int& o); - -struct tommath_int -{ - typedef mpl::list<boost::int32_t, boost::long_long_type> signed_types; - typedef mpl::list<boost::uint32_t, boost::ulong_long_type> unsigned_types; - typedef mpl::list<long double> float_types; - - tommath_int() - { - detail::check_tommath_result(mp_init(&m_data)); - } - tommath_int(const tommath_int& o) - { - detail::check_tommath_result(mp_init_copy(&m_data, const_cast< ::mp_int*>(&o.m_data))); - } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - tommath_int(tommath_int&& o) BOOST_NOEXCEPT - { - m_data = o.m_data; - o.m_data.dp = 0; - } - tommath_int& operator = (tommath_int&& o) - { - mp_exch(&m_data, &o.m_data); - return *this; - } -#endif - tommath_int& operator = (const tommath_int& o) - { - if(m_data.dp == 0) - detail::check_tommath_result(mp_init(&m_data)); - if(o.m_data.dp) - detail::check_tommath_result(mp_copy(const_cast< ::mp_int*>(&o.m_data), &m_data)); - return *this; - } - tommath_int& operator = (boost::ulong_long_type i) - { - if(m_data.dp == 0) - detail::check_tommath_result(mp_init(&m_data)); - boost::ulong_long_type mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); - unsigned shift = 0; - ::mp_int t; - detail::check_tommath_result(mp_init(&t)); - mp_zero(&m_data); - while(i) - { - detail::check_tommath_result(mp_set_int(&t, static_cast<unsigned>(i & mask))); - if(shift) - detail::check_tommath_result(mp_mul_2d(&t, shift, &t)); - detail::check_tommath_result((mp_add(&m_data, &t, &m_data))); - shift += std::numeric_limits<unsigned>::digits; - i >>= std::numeric_limits<unsigned>::digits; - } - mp_clear(&t); - return *this; - } - tommath_int& operator = (boost::long_long_type i) - { - if(m_data.dp == 0) - detail::check_tommath_result(mp_init(&m_data)); - bool neg = i < 0; - *this = boost::multiprecision::detail::unsigned_abs(i); - if(neg) - detail::check_tommath_result(mp_neg(&m_data, &m_data)); - return *this; - } - // - // Note that although mp_set_int takes an unsigned long as an argument - // it only sets the first 32-bits to the result, and ignores the rest. - // So use uint32_t as the largest type to pass to this function. - // - tommath_int& operator = (boost::uint32_t i) - { - if(m_data.dp == 0) - detail::check_tommath_result(mp_init(&m_data)); - detail::check_tommath_result((mp_set_int(&m_data, i))); - return *this; - } - tommath_int& operator = (boost::int32_t i) - { - if(m_data.dp == 0) - detail::check_tommath_result(mp_init(&m_data)); - bool neg = i < 0; - *this = boost::multiprecision::detail::unsigned_abs(i); - if(neg) - detail::check_tommath_result(mp_neg(&m_data, &m_data)); - return *this; - } - tommath_int& operator = (long double a) - { - using std::frexp; - using std::ldexp; - using std::floor; - - if(m_data.dp == 0) - detail::check_tommath_result(mp_init(&m_data)); - - if (a == 0) { - detail::check_tommath_result(mp_set_int(&m_data, 0)); - return *this; - } - - if (a == 1) { - detail::check_tommath_result(mp_set_int(&m_data, 1)); - return *this; - } - - BOOST_ASSERT(!(boost::math::isinf)(a)); - BOOST_ASSERT(!(boost::math::isnan)(a)); - - int e; - long double f, term; - detail::check_tommath_result(mp_set_int(&m_data, 0u)); - ::mp_int t; - detail::check_tommath_result(mp_init(&t)); - - f = frexp(a, &e); - - static const int shift = std::numeric_limits<int>::digits - 1; - - while(f) - { - // extract int sized bits from f: - f = ldexp(f, shift); - term = floor(f); - e -= shift; - detail::check_tommath_result(mp_mul_2d(&m_data, shift, &m_data)); - if(term > 0) - { - detail::check_tommath_result(mp_set_int(&t, static_cast<int>(term))); - detail::check_tommath_result(mp_add(&m_data, &t, &m_data)); - } - else - { - detail::check_tommath_result(mp_set_int(&t, static_cast<int>(-term))); - detail::check_tommath_result(mp_sub(&m_data, &t, &m_data)); - } - f -= term; - } - if(e > 0) - detail::check_tommath_result(mp_mul_2d(&m_data, e, &m_data)); - else if(e < 0) - { - tommath_int t2; - detail::check_tommath_result(mp_div_2d(&m_data, -e, &m_data, &t2.data())); - } - mp_clear(&t); - return *this; - } - tommath_int& operator = (const char* s) - { - // - // We don't use libtommath's own routine because it doesn't error check the input :-( - // - if(m_data.dp == 0) - detail::check_tommath_result(mp_init(&m_data)); - std::size_t n = s ? std::strlen(s) : 0; - *this = static_cast<boost::uint32_t>(0u); - unsigned radix = 10; - bool isneg = false; - if(n && (*s == '-')) - { - --n; - ++s; - isneg = true; - } - if(n && (*s == '0')) - { - if((n > 1) && ((s[1] == 'x') || (s[1] == 'X'))) - { - radix = 16; - s +=2; - n -= 2; - } - else - { - radix = 8; - n -= 1; - } - } - if(n) - { - if(radix == 8 || radix == 16) - { - unsigned shift = radix == 8 ? 3 : 4; - unsigned block_count = DIGIT_BIT / shift; - unsigned block_shift = shift * block_count; - boost::ulong_long_type val, block; - while(*s) - { - block = 0; - for(unsigned i = 0; (i < block_count); ++i) - { - if(*s >= '0' && *s <= '9') - val = *s - '0'; - else if(*s >= 'a' && *s <= 'f') - val = 10 + *s - 'a'; - else if(*s >= 'A' && *s <= 'F') - val = 10 + *s - 'A'; - else - val = 400; - if(val > radix) - { - BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string.")); - } - block <<= shift; - block |= val; - if(!*++s) - { - // final shift is different: - block_shift = (i + 1) * shift; - break; - } - } - detail::check_tommath_result(mp_mul_2d(&data(), block_shift, &data())); - if(data().used) - data().dp[0] |= block; - else - *this = block; - } - } - else - { - // Base 10, we extract blocks of size 10^9 at a time, that way - // the number of multiplications is kept to a minimum: - boost::uint32_t block_mult = 1000000000; - while(*s) - { - boost::uint32_t block = 0; - for(unsigned i = 0; i < 9; ++i) - { - boost::uint32_t val; - if(*s >= '0' && *s <= '9') - val = *s - '0'; - else - BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected character encountered in input.")); - block *= 10; - block += val; - if(!*++s) - { - static const boost::uint32_t block_multiplier[9] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - block_mult = block_multiplier[i]; - break; - } - } - tommath_int t; - t = block_mult; - eval_multiply(*this, t); - t = block; - eval_add(*this, t); - } - } - } - if(isneg) - this->negate(); - return *this; - } - std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const - { - BOOST_ASSERT(m_data.dp); - int base = 10; - if((f & std::ios_base::oct) == std::ios_base::oct) - base = 8; - else if((f & std::ios_base::hex) == std::ios_base::hex) - base = 16; - // - // sanity check, bases 8 and 16 are only available for positive numbers: - // - if((base != 10) && m_data.sign) - BOOST_THROW_EXCEPTION(std::runtime_error("Formatted output in bases 8 or 16 is only available for positive numbers")); - int s; - detail::check_tommath_result(mp_radix_size(const_cast< ::mp_int*>(&m_data), base, &s)); - boost::scoped_array<char> a(new char[s+1]); - detail::check_tommath_result(mp_toradix_n(const_cast< ::mp_int*>(&m_data), a.get(), base, s+1)); - std::string result = a.get(); - if((base != 10) && (f & std::ios_base::showbase)) - { - int pos = result[0] == '-' ? 1 : 0; - const char* pp = base == 8 ? "0" : "0x"; - result.insert(static_cast<std::string::size_type>(pos), pp); - } - if((f & std::ios_base::showpos) && (result[0] != '-')) - result.insert(static_cast<std::string::size_type>(0), 1, '+'); - return result; - } - ~tommath_int() - { - if(m_data.dp) - mp_clear(&m_data); - } - void negate() - { - BOOST_ASSERT(m_data.dp); - mp_neg(&m_data, &m_data); - } - int compare(const tommath_int& o)const - { - BOOST_ASSERT(m_data.dp && o.m_data.dp); - return mp_cmp(const_cast< ::mp_int*>(&m_data), const_cast< ::mp_int*>(&o.m_data)); - } - template <class V> - int compare(V v)const - { - tommath_int d; - tommath_int t(*this); - detail::check_tommath_result(mp_shrink(&t.data())); - d = v; - return t.compare(d); - } - ::mp_int& data() - { - BOOST_ASSERT(m_data.dp); - return m_data; - } - const ::mp_int& data()const - { - BOOST_ASSERT(m_data.dp); - return m_data; - } - void swap(tommath_int& o)BOOST_NOEXCEPT - { - mp_exch(&m_data, &o.data()); - } -protected: - ::mp_int m_data; -}; - -#define BOOST_MP_TOMMATH_BIT_OP_CHECK(x)\ - if(SIGN(&x.data()))\ - BOOST_THROW_EXCEPTION(std::runtime_error("Bitwise operations on libtommath negative valued integers are disabled as they produce unpredictable results")) - -int eval_get_sign(const tommath_int& val); - -inline void eval_add(tommath_int& t, const tommath_int& o) -{ - detail::check_tommath_result(mp_add(&t.data(), const_cast< ::mp_int*>(&o.data()), &t.data())); -} -inline void eval_subtract(tommath_int& t, const tommath_int& o) -{ - detail::check_tommath_result(mp_sub(&t.data(), const_cast< ::mp_int*>(&o.data()), &t.data())); -} -inline void eval_multiply(tommath_int& t, const tommath_int& o) -{ - detail::check_tommath_result(mp_mul(&t.data(), const_cast< ::mp_int*>(&o.data()), &t.data())); -} -inline void eval_divide(tommath_int& t, const tommath_int& o) -{ - using default_ops::eval_is_zero; - tommath_int temp; - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - detail::check_tommath_result(mp_div(&t.data(), const_cast< ::mp_int*>(&o.data()), &t.data(), &temp.data())); -} -inline void eval_modulus(tommath_int& t, const tommath_int& o) -{ - using default_ops::eval_is_zero; - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - bool neg = eval_get_sign(t) < 0; - bool neg2 = eval_get_sign(o) < 0; - detail::check_tommath_result(mp_mod(&t.data(), const_cast< ::mp_int*>(&o.data()), &t.data())); - if((neg != neg2) && (eval_get_sign(t) != 0)) - { - t.negate(); - detail::check_tommath_result(mp_add(&t.data(), const_cast< ::mp_int*>(&o.data()), &t.data())); - t.negate(); - } - else if(neg && (t.compare(o) == 0)) - { - mp_zero(&t.data()); - } -} -template <class UI> -inline void eval_left_shift(tommath_int& t, UI i) -{ - detail::check_tommath_result(mp_mul_2d(&t.data(), static_cast<unsigned>(i), &t.data())); -} -template <class UI> -inline void eval_right_shift(tommath_int& t, UI i) -{ - using default_ops::eval_increment; - using default_ops::eval_decrement; - bool neg = eval_get_sign(t) < 0; - tommath_int d; - if(neg) - eval_increment(t); - detail::check_tommath_result(mp_div_2d(&t.data(), static_cast<unsigned>(i), &t.data(), &d.data())); - if(neg) - eval_decrement(t); -} -template <class UI> -inline void eval_left_shift(tommath_int& t, const tommath_int& v, UI i) -{ - detail::check_tommath_result(mp_mul_2d(const_cast< ::mp_int*>(&v.data()), static_cast<unsigned>(i), &t.data())); -} -/* -template <class UI> -inline void eval_right_shift(tommath_int& t, const tommath_int& v, UI i) -{ - tommath_int d; - detail::check_tommath_result(mp_div_2d(const_cast< ::mp_int*>(&v.data()), static_cast<unsigned long>(i), &t.data(), &d.data())); -} -*/ -inline void eval_bitwise_and(tommath_int& result, const tommath_int& v) -{ - BOOST_MP_TOMMATH_BIT_OP_CHECK(result); - BOOST_MP_TOMMATH_BIT_OP_CHECK(v); - detail::check_tommath_result(mp_and(&result.data(), const_cast< ::mp_int*>(&v.data()), &result.data())); -} - -inline void eval_bitwise_or(tommath_int& result, const tommath_int& v) -{ - BOOST_MP_TOMMATH_BIT_OP_CHECK(result); - BOOST_MP_TOMMATH_BIT_OP_CHECK(v); - detail::check_tommath_result(mp_or(&result.data(), const_cast< ::mp_int*>(&v.data()), &result.data())); -} - -inline void eval_bitwise_xor(tommath_int& result, const tommath_int& v) -{ - BOOST_MP_TOMMATH_BIT_OP_CHECK(result); - BOOST_MP_TOMMATH_BIT_OP_CHECK(v); - detail::check_tommath_result(mp_xor(&result.data(), const_cast< ::mp_int*>(&v.data()), &result.data())); -} - -inline void eval_add(tommath_int& t, const tommath_int& p, const tommath_int& o) -{ - detail::check_tommath_result(mp_add(const_cast< ::mp_int*>(&p.data()), const_cast< ::mp_int*>(&o.data()), &t.data())); -} -inline void eval_subtract(tommath_int& t, const tommath_int& p, const tommath_int& o) -{ - detail::check_tommath_result(mp_sub(const_cast< ::mp_int*>(&p.data()), const_cast< ::mp_int*>(&o.data()), &t.data())); -} -inline void eval_multiply(tommath_int& t, const tommath_int& p, const tommath_int& o) -{ - detail::check_tommath_result(mp_mul(const_cast< ::mp_int*>(&p.data()), const_cast< ::mp_int*>(&o.data()), &t.data())); -} -inline void eval_divide(tommath_int& t, const tommath_int& p, const tommath_int& o) -{ - using default_ops::eval_is_zero; - tommath_int d; - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - detail::check_tommath_result(mp_div(const_cast< ::mp_int*>(&p.data()), const_cast< ::mp_int*>(&o.data()), &t.data(), &d.data())); -} -inline void eval_modulus(tommath_int& t, const tommath_int& p, const tommath_int& o) -{ - using default_ops::eval_is_zero; - if(eval_is_zero(o)) - BOOST_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - bool neg = eval_get_sign(p) < 0; - bool neg2 = eval_get_sign(o) < 0; - detail::check_tommath_result(mp_mod(const_cast< ::mp_int*>(&p.data()), const_cast< ::mp_int*>(&o.data()), &t.data())); - if((neg != neg2) && (eval_get_sign(t) != 0)) - { - t.negate(); - detail::check_tommath_result(mp_add(&t.data(), const_cast< ::mp_int*>(&o.data()), &t.data())); - t.negate(); - } - else if(neg && (t.compare(o) == 0)) - { - mp_zero(&t.data()); - } -} - -inline void eval_bitwise_and(tommath_int& result, const tommath_int& u, const tommath_int& v) -{ - BOOST_MP_TOMMATH_BIT_OP_CHECK(u); - BOOST_MP_TOMMATH_BIT_OP_CHECK(v); - detail::check_tommath_result(mp_and(const_cast< ::mp_int*>(&u.data()), const_cast< ::mp_int*>(&v.data()), &result.data())); -} - -inline void eval_bitwise_or(tommath_int& result, const tommath_int& u, const tommath_int& v) -{ - BOOST_MP_TOMMATH_BIT_OP_CHECK(u); - BOOST_MP_TOMMATH_BIT_OP_CHECK(v); - detail::check_tommath_result(mp_or(const_cast< ::mp_int*>(&u.data()), const_cast< ::mp_int*>(&v.data()), &result.data())); -} - -inline void eval_bitwise_xor(tommath_int& result, const tommath_int& u, const tommath_int& v) -{ - BOOST_MP_TOMMATH_BIT_OP_CHECK(u); - BOOST_MP_TOMMATH_BIT_OP_CHECK(v); - detail::check_tommath_result(mp_xor(const_cast< ::mp_int*>(&u.data()), const_cast< ::mp_int*>(&v.data()), &result.data())); -} -/* -inline void eval_complement(tommath_int& result, const tommath_int& u) -{ - // - // Although this code works, it doesn't really do what the user might expect.... - // and it's hard to see how it ever could. Disabled for now: - // - result = u; - for(int i = 0; i < result.data().used; ++i) - { - result.data().dp[i] = MP_MASK & ~(result.data().dp[i]); - } - // - // We now need to pad out the left of the value with 1's to round up to a whole number of - // CHAR_BIT * sizeof(mp_digit) units. Otherwise we'll end up with a very strange number of - // bits set! - // - unsigned shift = result.data().used * DIGIT_BIT; // How many bits we're actually using - // How many bits we actually need, reduced by one to account for a mythical sign bit: - int padding = result.data().used * std::numeric_limits<mp_digit>::digits - shift - 1; - while(padding >= std::numeric_limits<mp_digit>::digits) - padding -= std::numeric_limits<mp_digit>::digits; - - // Create a mask providing the extra bits we need and add to result: - tommath_int mask; - mask = static_cast<boost::long_long_type>((1u << padding) - 1); - eval_left_shift(mask, shift); - add(result, mask); -} -*/ -inline bool eval_is_zero(const tommath_int& val) -{ - return mp_iszero(&val.data()); -} -inline int eval_get_sign(const tommath_int& val) -{ - return mp_iszero(&val.data()) ? 0 : SIGN(&val.data()) ? -1 : 1; -} -/* -template <class A> -inline void eval_convert_to(A* result, const tommath_int& val) -{ - *result = boost::lexical_cast<A>(val.str(0, std::ios_base::fmtflags(0))); -} -inline void eval_convert_to(char* result, const tommath_int& val) -{ - *result = static_cast<char>(boost::lexical_cast<int>(val.str(0, std::ios_base::fmtflags(0)))); -} -inline void eval_convert_to(unsigned char* result, const tommath_int& val) -{ - *result = static_cast<unsigned char>(boost::lexical_cast<unsigned>(val.str(0, std::ios_base::fmtflags(0)))); -} -inline void eval_convert_to(signed char* result, const tommath_int& val) -{ - *result = static_cast<signed char>(boost::lexical_cast<int>(val.str(0, std::ios_base::fmtflags(0)))); -} -*/ -inline void eval_abs(tommath_int& result, const tommath_int& val) -{ - detail::check_tommath_result(mp_abs(const_cast< ::mp_int*>(&val.data()), &result.data())); -} -inline void eval_gcd(tommath_int& result, const tommath_int& a, const tommath_int& b) -{ - detail::check_tommath_result(mp_gcd(const_cast< ::mp_int*>(&a.data()), const_cast< ::mp_int*>(&b.data()), const_cast< ::mp_int*>(&result.data()))); -} -inline void eval_lcm(tommath_int& result, const tommath_int& a, const tommath_int& b) -{ - detail::check_tommath_result(mp_lcm(const_cast< ::mp_int*>(&a.data()), const_cast< ::mp_int*>(&b.data()), const_cast< ::mp_int*>(&result.data()))); -} -inline void eval_powm(tommath_int& result, const tommath_int& base, const tommath_int& p, const tommath_int& m) -{ - if(eval_get_sign(p) < 0) - { - BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } - detail::check_tommath_result(mp_exptmod(const_cast< ::mp_int*>(&base.data()), const_cast< ::mp_int*>(&p.data()), const_cast< ::mp_int*>(&m.data()), &result.data())); -} - - -inline void eval_qr(const tommath_int& x, const tommath_int& y, - tommath_int& q, tommath_int& r) -{ - detail::check_tommath_result(mp_div(const_cast< ::mp_int*>(&x.data()), const_cast< ::mp_int*>(&y.data()), &q.data(), &r.data())); -} - -inline unsigned eval_lsb(const tommath_int& val) -{ - int c = eval_get_sign(val); - if(c == 0) - { - BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand.")); - } - if(c < 0) - { - BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - return mp_cnt_lsb(const_cast< ::mp_int*>(&val.data())); -} - -inline unsigned eval_msb(const tommath_int& val) -{ - int c = eval_get_sign(val); - if(c == 0) - { - BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand.")); - } - if(c < 0) - { - BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - return mp_count_bits(const_cast< ::mp_int*>(&val.data())) - 1; -} - -template <class Integer> -inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const tommath_int& x, Integer val) -{ - static const mp_digit m = (static_cast<mp_digit>(1) << DIGIT_BIT) - 1; - if(val <= m) - { - mp_digit d; - detail::check_tommath_result(mp_mod_d(const_cast< ::mp_int*>(&x.data()), static_cast<mp_digit>(val), &d)); - return d; - } - else - { - return default_ops::eval_integer_modulus(x, val); - } -} -template <class Integer> -inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const tommath_int& x, Integer val) -{ - return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); -} - -inline std::size_t hash_value(const tommath_int& val) -{ - std::size_t result = 0; - std::size_t len = val.data().used; - for(std::size_t i = 0; i < len; ++i) - boost::hash_combine(result, val.data().dp[i]); - boost::hash_combine(result, val.data().sign); - return result; -} - -} // namespace backends - -using boost::multiprecision::backends::tommath_int; - -template<> -struct number_category<tommath_int> : public mpl::int_<number_kind_integer>{}; - -typedef number<tommath_int > tom_int; -typedef rational_adaptor<tommath_int> tommath_rational; -typedef number<tommath_rational> tom_rational; - -}} // namespaces - -namespace std{ - -template<boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> > -{ - typedef boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> number_type; -public: - BOOST_STATIC_CONSTEXPR bool is_specialized = true; - // - // Largest and smallest numbers are bounded only by available memory, set - // to zero: - // - static number_type (min)() - { - return number_type(); - } - static number_type (max)() - { - return number_type(); - } - static number_type lowest() { return (min)(); } - BOOST_STATIC_CONSTEXPR int digits = INT_MAX; - BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L; - BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3; - BOOST_STATIC_CONSTEXPR bool is_signed = true; - BOOST_STATIC_CONSTEXPR bool is_integer = true; - BOOST_STATIC_CONSTEXPR bool is_exact = true; - BOOST_STATIC_CONSTEXPR int radix = 2; - static number_type epsilon() { return number_type(); } - static number_type round_error() { return number_type(); } - BOOST_STATIC_CONSTEXPR int min_exponent = 0; - BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; - BOOST_STATIC_CONSTEXPR int max_exponent = 0; - BOOST_STATIC_CONSTEXPR int max_exponent10 = 0; - BOOST_STATIC_CONSTEXPR bool has_infinity = false; - BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false; - BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; - BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; - BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - static number_type infinity() { return number_type(); } - static number_type quiet_NaN() { return number_type(); } - static number_type signaling_NaN() { return number_type(); } - static number_type denorm_min() { return number_type(); } - BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR bool is_bounded = false; - BOOST_STATIC_CONSTEXPR bool is_modulo = false; - BOOST_STATIC_CONSTEXPR bool traps = false; - BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero; -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::digits; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::max_digits10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::is_signed; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::is_integer; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::is_exact; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::radix; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::min_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::min_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::max_exponent; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::max_exponent10; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::has_infinity; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::has_quiet_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::has_signaling_NaN; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::has_denorm; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::has_denorm_loss; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::is_iec559; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::is_bounded; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::is_modulo; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::traps; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::tinyness_before; -template <boost::multiprecision::expression_template_option ExpressionTemplates> -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::tommath_int, ExpressionTemplates> >::round_style; - -#endif -} - -#endif diff --git a/contrib/restricted/boost/boost/multiprecision/traits/extract_exponent_type.hpp b/contrib/restricted/boost/boost/multiprecision/traits/extract_exponent_type.hpp deleted file mode 100644 index adb30d5436..0000000000 --- a/contrib/restricted/boost/boost/multiprecision/traits/extract_exponent_type.hpp +++ /dev/null @@ -1,28 +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_ - -#ifndef BOOST_MATH_EXTRACT_EXPONENT_HPP -#define BOOST_MATH_EXTRACT_EXPONENT_HPP - -#include <boost/multiprecision/number.hpp> - -namespace boost{ -namespace multiprecision{ -namespace backends{ - -template <class Backend, int cat> -struct extract_exponent_type -{ - typedef int type; -}; -template <class Backend> -struct extract_exponent_type<Backend, number_kind_floating_point> -{ - typedef typename Backend::exponent_type type; -}; - -}}} // namespaces - -#endif diff --git a/contrib/restricted/boost/multiprecision/CMakeLists.txt b/contrib/restricted/boost/multiprecision/CMakeLists.txt new file mode 100644 index 0000000000..b7fb0528f6 --- /dev/null +++ b/contrib/restricted/boost/multiprecision/CMakeLists.txt @@ -0,0 +1,33 @@ + +# This file was gererated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_library(restricted-boost-multiprecision INTERFACE) +target_include_directories(restricted-boost-multiprecision INTERFACE + ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/multiprecision/include +) +target_link_libraries(restricted-boost-multiprecision INTERFACE + contrib-libs-cxxsupp + yutil + restricted-boost-array + restricted-boost-assert + restricted-boost-config + restricted-boost-container_hash + restricted-boost-core + restricted-boost-integer + restricted-boost-lexical_cast + restricted-boost-math + restricted-boost-mpl + restricted-boost-predef + restricted-boost-random + restricted-boost-rational + restricted-boost-smart_ptr + restricted-boost-static_assert + restricted-boost-throw_exception + restricted-boost-type_traits +) diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int.hpp index 8490541159..59f6c955d8 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int.hpp @@ -842,7 +842,7 @@ public: m_sign = false; } } - BOOST_MP_FORCEINLINE void resize(unsigned /*new_size*/, unsigned min_size) + BOOST_MP_FORCEINLINE void resize(unsigned /* new_size */, unsigned min_size) { detail::verify_new_size(2, min_size, checked_type()); } diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/add.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add.hpp index f8ec7bb135..f8ec7bb135 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/add.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/bitwise.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/bitwise.hpp index 168544c9bb..168544c9bb 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/bitwise.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/bitwise.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/checked.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/checked.hpp index cafe50ea49..cafe50ea49 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/checked.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/checked.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/comparison.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/comparison.hpp index 8d8e7aacb8..8d8e7aacb8 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/comparison.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/comparison.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/cpp_int_config.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/cpp_int_config.hpp index eb88f3da80..eb88f3da80 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/cpp_int_config.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/cpp_int_config.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/divide.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/divide.hpp index 81583ec384..81583ec384 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/divide.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/divide.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/import_export.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/import_export.hpp index b975a79663..b975a79663 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/import_export.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/import_export.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/limits.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/limits.hpp index b19e1ebbe6..b19e1ebbe6 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/limits.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/limits.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/literals.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/literals.hpp index ce30fd8484..ce30fd8484 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/literals.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/literals.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/misc.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/misc.hpp index abbdc295d0..abbdc295d0 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/misc.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/misc.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/multiply.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/multiply.hpp index 151b2294c7..151b2294c7 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/multiply.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/multiply.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/serialize.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/serialize.hpp index 042a9f89f7..042a9f89f7 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/serialize.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/serialize.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/cpp_int/value_pack.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/value_pack.hpp index 29d9562e04..29d9562e04 100644 --- a/contrib/restricted/boost/boost/multiprecision/cpp_int/value_pack.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/value_pack.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/bitscan.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/bitscan.hpp index c12606551f..c12606551f 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/bitscan.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/bitscan.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/default_ops.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/default_ops.hpp index c45eec447f..c45eec447f 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/default_ops.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/default_ops.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/et_ops.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/et_ops.hpp index 3778e01029..3778e01029 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/et_ops.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/et_ops.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/functions/constants.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/constants.hpp index 48b4a5c29a..48b4a5c29a 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/functions/constants.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/constants.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/functions/pow.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/pow.hpp index 179e37f400..179e37f400 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/functions/pow.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/pow.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/functions/trig.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trig.hpp index c001f955c9..c001f955c9 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/functions/trig.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trig.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/generic_interconvert.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/generic_interconvert.hpp index ac3fe6640b..ac3fe6640b 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/generic_interconvert.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/generic_interconvert.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/integer_ops.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/integer_ops.hpp index 4b1a9d8bae..4b1a9d8bae 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/integer_ops.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/integer_ops.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/min_max.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/min_max.hpp index 56ac5346cf..56ac5346cf 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/min_max.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/min_max.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/no_et_ops.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_et_ops.hpp index 2faee69d03..2faee69d03 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/no_et_ops.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_et_ops.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/number_base.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_base.hpp index 24e0299b15..24e0299b15 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/number_base.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_base.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/number_compare.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_compare.hpp index adf034265c..adf034265c 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/number_compare.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_compare.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/detail/ublas_interop.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/ublas_interop.hpp index cf56dc9fb8..cf56dc9fb8 100644 --- a/contrib/restricted/boost/boost/multiprecision/detail/ublas_interop.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/ublas_interop.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/number.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/number.hpp index f99ef2a970..f99ef2a970 100644 --- a/contrib/restricted/boost/boost/multiprecision/number.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/number.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/rational_adaptor.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/rational_adaptor.hpp index 4ba5961a11..4ba5961a11 100644 --- a/contrib/restricted/boost/boost/multiprecision/rational_adaptor.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/rational_adaptor.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/traits/explicit_conversion.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/explicit_conversion.hpp index 0a14f03442..0a14f03442 100644 --- a/contrib/restricted/boost/boost/multiprecision/traits/explicit_conversion.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/explicit_conversion.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/traits/is_backend.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_backend.hpp index 2a26b19df0..2a26b19df0 100644 --- a/contrib/restricted/boost/boost/multiprecision/traits/is_backend.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_backend.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/traits/is_byte_container.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_byte_container.hpp index d97428f0f2..d97428f0f2 100644 --- a/contrib/restricted/boost/boost/multiprecision/traits/is_byte_container.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_byte_container.hpp diff --git a/contrib/restricted/boost/boost/multiprecision/traits/is_restricted_conversion.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_restricted_conversion.hpp index ff8f7f63cb..ff8f7f63cb 100644 --- a/contrib/restricted/boost/boost/multiprecision/traits/is_restricted_conversion.hpp +++ b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_restricted_conversion.hpp |