Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Copyright 2011 John Maddock. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_MATH_BN_MPFR_HPP Chris@16: #define BOOST_MATH_BN_MPFR_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost{ Chris@16: namespace multiprecision{ Chris@16: Chris@16: enum mpfr_allocation_type Chris@16: { Chris@16: allocate_stack, Chris@16: allocate_dynamic Chris@16: }; Chris@16: Chris@16: namespace backends{ Chris@16: Chris@16: template Chris@16: struct mpfr_float_backend; Chris@16: Chris@16: } // namespace backends Chris@16: Chris@16: template Chris@16: struct number_category > : public mpl::int_{}; Chris@16: Chris@16: namespace backends{ Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: template Chris@16: struct mpfr_cleanup Chris@16: { Chris@16: struct initializer Chris@16: { Chris@16: initializer() {} Chris@16: ~initializer(){ mpfr_free_cache(); } Chris@16: void force_instantiate()const {} Chris@16: }; Chris@16: static const initializer init; Chris@16: static void force_instantiate() { init.force_instantiate(); } Chris@16: }; Chris@16: Chris@16: template Chris@16: typename mpfr_cleanup::initializer const mpfr_cleanup::init; Chris@16: Chris@16: inline long get_default_precision() { return 50; } Chris@16: Chris@16: template Chris@16: struct mpfr_float_imp; Chris@16: Chris@16: template Chris@16: struct mpfr_float_imp Chris@16: { Chris@16: typedef mpl::list signed_types; Chris@16: typedef mpl::list unsigned_types; Chris@16: typedef mpl::list float_types; Chris@16: typedef long exponent_type; Chris@16: Chris@16: mpfr_float_imp() Chris@16: { Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: } Chris@16: mpfr_float_imp(unsigned prec) Chris@16: { Chris@16: mpfr_init2(m_data, prec); Chris@16: } Chris@16: Chris@16: mpfr_float_imp(const mpfr_float_imp& o) Chris@16: { Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: if(o.m_data[0]._mpfr_d) Chris@16: mpfr_set(m_data, o.m_data, GMP_RNDN); Chris@16: } Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: mpfr_float_imp(mpfr_float_imp&& o) BOOST_NOEXCEPT Chris@16: { Chris@16: m_data[0] = o.m_data[0]; Chris@16: o.m_data[0]._mpfr_d = 0; Chris@16: } Chris@16: #endif Chris@16: mpfr_float_imp& operator = (const mpfr_float_imp& o) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: if(o.m_data[0]._mpfr_d) Chris@16: mpfr_set(m_data, o.m_data, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: mpfr_float_imp& operator = (mpfr_float_imp&& o) BOOST_NOEXCEPT Chris@16: { Chris@16: mpfr_swap(m_data, o.m_data); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: #ifdef _MPFR_H_HAVE_INTMAX_T Chris@16: mpfr_float_imp& operator = (unsigned long long i) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: mpfr_set_uj(m_data, i, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (long long i) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: mpfr_set_sj(m_data, i, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: mpfr_float_imp& operator = (unsigned long long i) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); Chris@16: unsigned shift = 0; Chris@16: mpfr_t t; Chris@16: mpfr_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); Chris@16: mpfr_set_ui(m_data, 0, GMP_RNDN); Chris@16: while(i) Chris@16: { Chris@16: mpfr_set_ui(t, static_cast(i & mask), GMP_RNDN); Chris@16: if(shift) Chris@16: mpfr_mul_2exp(t, t, shift, GMP_RNDN); Chris@16: mpfr_add(m_data, m_data, t, GMP_RNDN); Chris@16: shift += std::numeric_limits::digits; Chris@16: i >>= std::numeric_limits::digits; Chris@16: } Chris@16: mpfr_clear(t); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (long long i) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: bool neg = i < 0; Chris@101: *this = boost::multiprecision::detail::unsigned_abs(i); Chris@16: if(neg) Chris@16: mpfr_neg(m_data, m_data, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: mpfr_float_imp& operator = (unsigned long i) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: mpfr_set_ui(m_data, i, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (long i) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: mpfr_set_si(m_data, i, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (double d) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: mpfr_set_d(m_data, d, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (long double a) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: mpfr_set_ld(m_data, a, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (const char* s) Chris@16: { Chris@16: if(m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); Chris@16: if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0) Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number."))); Chris@16: } Chris@16: return *this; Chris@16: } Chris@16: void swap(mpfr_float_imp& o) BOOST_NOEXCEPT Chris@16: { Chris@16: mpfr_swap(m_data, o.m_data); Chris@16: } Chris@16: std::string str(std::streamsize digits, std::ios_base::fmtflags f)const Chris@16: { Chris@16: BOOST_ASSERT(m_data[0]._mpfr_d); Chris@16: Chris@16: bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific; Chris@16: bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed; Chris@16: Chris@16: std::streamsize org_digits(digits); Chris@16: Chris@16: if(scientific && digits) Chris@16: ++digits; Chris@16: Chris@16: std::string result; Chris@16: mp_exp_t e; Chris@16: if(mpfr_inf_p(m_data)) Chris@16: { Chris@16: if(mpfr_sgn(m_data) < 0) Chris@16: result = "-inf"; Chris@16: else if(f & std::ios_base::showpos) Chris@16: result = "+inf"; Chris@16: else Chris@16: result = "inf"; Chris@16: return result; Chris@16: } Chris@16: if(mpfr_nan_p(m_data)) Chris@16: { Chris@16: result = "nan"; Chris@16: return result; Chris@16: } Chris@16: if(mpfr_zero_p(m_data)) Chris@16: { Chris@16: e = 0; Chris@16: result = "0"; Chris@16: } Chris@16: else Chris@16: { Chris@16: char* ps = mpfr_get_str (0, &e, 10, static_cast(digits), m_data, GMP_RNDN); Chris@16: --e; // To match with what our formatter expects. Chris@16: if(fixed && e != -1) Chris@16: { Chris@16: // Oops we actually need a different number of digits to what we asked for: Chris@16: mpfr_free_str(ps); Chris@16: digits += e + 1; Chris@16: if(digits == 0) Chris@16: { Chris@16: // We need to get *all* the digits and then possibly round up, Chris@16: // we end up with either "0" or "1" as the result. Chris@16: ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN); Chris@16: --e; Chris@16: unsigned offset = *ps == '-' ? 1 : 0; Chris@16: if(ps[offset] > '5') Chris@16: { Chris@16: ++e; Chris@16: ps[offset] = '1'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: else if(ps[offset] == '5') Chris@16: { Chris@16: unsigned i = offset + 1; Chris@16: bool round_up = false; Chris@16: while(ps[i] != 0) Chris@16: { Chris@16: if(ps[i] != '0') Chris@16: { Chris@16: round_up = true; Chris@16: break; Chris@16: } Chris@16: } Chris@16: if(round_up) Chris@16: { Chris@16: ++e; Chris@16: ps[offset] = '1'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: else Chris@16: { Chris@16: ps[offset] = '0'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: } Chris@16: else Chris@16: { Chris@16: ps[offset] = '0'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: } Chris@16: else if(digits > 0) Chris@16: { Chris@16: ps = mpfr_get_str (0, &e, 10, static_cast(digits), m_data, GMP_RNDN); Chris@16: --e; // To match with what our formatter expects. Chris@16: } Chris@16: else Chris@16: { Chris@16: ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN); Chris@16: --e; Chris@16: unsigned offset = *ps == '-' ? 1 : 0; Chris@16: ps[offset] = '0'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: } Chris@16: result = ps ? ps : "0"; Chris@16: if(ps) Chris@16: mpfr_free_str(ps); Chris@16: } Chris@16: boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data)); Chris@16: return result; Chris@16: } Chris@16: ~mpfr_float_imp() BOOST_NOEXCEPT Chris@16: { Chris@16: if(m_data[0]._mpfr_d) Chris@16: mpfr_clear(m_data); Chris@16: detail::mpfr_cleanup::force_instantiate(); Chris@16: } Chris@16: void negate() BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_data[0]._mpfr_d); Chris@16: mpfr_neg(m_data, m_data, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: int compare(const mpfr_float_backend& o)const BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d); Chris@16: return mpfr_cmp(m_data, o.m_data); Chris@16: } Chris@16: int compare(long i)const BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_data[0]._mpfr_d); Chris@16: return mpfr_cmp_si(m_data, i); Chris@16: } Chris@16: int compare(unsigned long i)const BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_data[0]._mpfr_d); Chris@16: return mpfr_cmp_ui(m_data, i); Chris@16: } Chris@16: template Chris@16: int compare(V v)const BOOST_NOEXCEPT Chris@16: { Chris@16: mpfr_float_backend d; Chris@16: d = v; Chris@16: return compare(d); Chris@16: } Chris@16: mpfr_t& data() BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_data[0]._mpfr_d); Chris@16: return m_data; Chris@16: } Chris@16: const mpfr_t& data()const BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_data[0]._mpfr_d); Chris@16: return m_data; Chris@16: } Chris@16: protected: Chris@16: mpfr_t m_data; Chris@16: static unsigned& get_default_precision() BOOST_NOEXCEPT Chris@16: { Chris@16: static unsigned val = 50; Chris@16: return val; Chris@16: } Chris@16: }; Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(push) Chris@16: #pragma warning(disable:4127) // Conditional expression is constant Chris@16: #endif Chris@16: Chris@16: template Chris@16: struct mpfr_float_imp Chris@16: { Chris@16: typedef mpl::list signed_types; Chris@16: typedef mpl::list unsigned_types; Chris@16: typedef mpl::list float_types; Chris@16: typedef long exponent_type; Chris@16: Chris@16: static const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u); Chris@16: static const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t); Chris@16: Chris@16: ~mpfr_float_imp() BOOST_NOEXCEPT Chris@16: { Chris@16: detail::mpfr_cleanup::force_instantiate(); Chris@16: } Chris@16: mpfr_float_imp() Chris@16: { Chris@16: mpfr_custom_init(m_buffer, digits2); Chris@16: mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer); Chris@16: } Chris@16: Chris@16: mpfr_float_imp(const mpfr_float_imp& o) Chris@16: { Chris@16: mpfr_custom_init(m_buffer, digits2); Chris@16: mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer); Chris@16: mpfr_set(m_data, o.m_data, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_imp& operator = (const mpfr_float_imp& o) Chris@16: { Chris@16: mpfr_set(m_data, o.m_data, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: #ifdef _MPFR_H_HAVE_INTMAX_T Chris@16: mpfr_float_imp& operator = (unsigned long long i) Chris@16: { Chris@16: mpfr_set_uj(m_data, i, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (long long i) Chris@16: { Chris@16: mpfr_set_sj(m_data, i, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: mpfr_float_imp& operator = (unsigned long long i) Chris@16: { Chris@16: unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); Chris@16: unsigned shift = 0; Chris@16: mpfr_t t; Chris@16: mp_limb_t t_limbs[limb_count]; Chris@16: mpfr_custom_init(t_limbs, digits2); Chris@16: mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs); Chris@16: mpfr_set_ui(m_data, 0, GMP_RNDN); Chris@16: while(i) Chris@16: { Chris@16: mpfr_set_ui(t, static_cast(i & mask), GMP_RNDN); Chris@16: if(shift) Chris@16: mpfr_mul_2exp(t, t, shift, GMP_RNDN); Chris@16: mpfr_add(m_data, m_data, t, GMP_RNDN); Chris@16: shift += std::numeric_limits::digits; Chris@16: i >>= std::numeric_limits::digits; Chris@16: } Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (long long i) Chris@16: { Chris@16: bool neg = i < 0; Chris@101: *this = boost::multiprecision::detail::unsigned_abs(i); Chris@16: if(neg) Chris@16: mpfr_neg(m_data, m_data, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: mpfr_float_imp& operator = (unsigned long i) Chris@16: { Chris@16: mpfr_set_ui(m_data, i, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (long i) Chris@16: { Chris@16: mpfr_set_si(m_data, i, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (double d) Chris@16: { Chris@16: mpfr_set_d(m_data, d, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (long double a) Chris@16: { Chris@16: mpfr_set_ld(m_data, a, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_imp& operator = (const char* s) Chris@16: { Chris@16: if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0) Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number."))); Chris@16: } Chris@16: return *this; Chris@16: } Chris@16: void swap(mpfr_float_imp& o) BOOST_NOEXCEPT Chris@16: { Chris@16: // We have to swap by copying: Chris@16: mpfr_float_imp t(*this); Chris@16: *this = o; Chris@16: o = t; Chris@16: } Chris@16: std::string str(std::streamsize digits, std::ios_base::fmtflags f)const Chris@16: { Chris@16: BOOST_ASSERT(m_data[0]._mpfr_d); Chris@16: Chris@16: bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific; Chris@16: bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed; Chris@16: Chris@16: std::streamsize org_digits(digits); Chris@16: Chris@16: if(scientific && digits) Chris@16: ++digits; Chris@16: Chris@16: std::string result; Chris@16: mp_exp_t e; Chris@16: if(mpfr_inf_p(m_data)) Chris@16: { Chris@16: if(mpfr_sgn(m_data) < 0) Chris@16: result = "-inf"; Chris@16: else if(f & std::ios_base::showpos) Chris@16: result = "+inf"; Chris@16: else Chris@16: result = "inf"; Chris@16: return result; Chris@16: } Chris@16: if(mpfr_nan_p(m_data)) Chris@16: { Chris@16: result = "nan"; Chris@16: return result; Chris@16: } Chris@16: if(mpfr_zero_p(m_data)) Chris@16: { Chris@16: e = 0; Chris@16: result = "0"; Chris@16: } Chris@16: else Chris@16: { Chris@16: char* ps = mpfr_get_str (0, &e, 10, static_cast(digits), m_data, GMP_RNDN); Chris@16: --e; // To match with what our formatter expects. Chris@16: if(fixed && e != -1) Chris@16: { Chris@16: // Oops we actually need a different number of digits to what we asked for: Chris@16: mpfr_free_str(ps); Chris@16: digits += e + 1; Chris@16: if(digits == 0) Chris@16: { Chris@16: // We need to get *all* the digits and then possibly round up, Chris@16: // we end up with either "0" or "1" as the result. Chris@16: ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN); Chris@16: --e; Chris@16: unsigned offset = *ps == '-' ? 1 : 0; Chris@16: if(ps[offset] > '5') Chris@16: { Chris@16: ++e; Chris@16: ps[offset] = '1'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: else if(ps[offset] == '5') Chris@16: { Chris@16: unsigned i = offset + 1; Chris@16: bool round_up = false; Chris@16: while(ps[i] != 0) Chris@16: { Chris@16: if(ps[i] != '0') Chris@16: { Chris@16: round_up = true; Chris@16: break; Chris@16: } Chris@16: } Chris@16: if(round_up) Chris@16: { Chris@16: ++e; Chris@16: ps[offset] = '1'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: else Chris@16: { Chris@16: ps[offset] = '0'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: } Chris@16: else Chris@16: { Chris@16: ps[offset] = '0'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: } Chris@16: else if(digits > 0) Chris@16: { Chris@16: ps = mpfr_get_str (0, &e, 10, static_cast(digits), m_data, GMP_RNDN); Chris@16: --e; // To match with what our formatter expects. Chris@16: } Chris@16: else Chris@16: { Chris@16: ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN); Chris@16: --e; Chris@16: unsigned offset = *ps == '-' ? 1 : 0; Chris@16: ps[offset] = '0'; Chris@16: ps[offset + 1] = 0; Chris@16: } Chris@16: } Chris@16: result = ps ? ps : "0"; Chris@16: if(ps) Chris@16: mpfr_free_str(ps); Chris@16: } Chris@16: boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data)); Chris@16: return result; Chris@16: } Chris@16: void negate() BOOST_NOEXCEPT Chris@16: { Chris@16: mpfr_neg(m_data, m_data, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: int compare(const mpfr_float_backend& o)const BOOST_NOEXCEPT Chris@16: { Chris@16: return mpfr_cmp(m_data, o.m_data); Chris@16: } Chris@16: int compare(long i)const BOOST_NOEXCEPT Chris@16: { Chris@16: return mpfr_cmp_si(m_data, i); Chris@16: } Chris@16: int compare(unsigned long i)const BOOST_NOEXCEPT Chris@16: { Chris@16: return mpfr_cmp_ui(m_data, i); Chris@16: } Chris@16: template Chris@16: int compare(V v)const BOOST_NOEXCEPT Chris@16: { Chris@16: mpfr_float_backend d; Chris@16: d = v; Chris@16: return compare(d); Chris@16: } Chris@16: mpfr_t& data() BOOST_NOEXCEPT Chris@16: { Chris@16: return m_data; Chris@16: } Chris@16: const mpfr_t& data()const BOOST_NOEXCEPT Chris@16: { Chris@16: return m_data; Chris@16: } Chris@16: protected: Chris@16: mpfr_t m_data; Chris@16: mp_limb_t m_buffer[limb_count]; Chris@16: }; Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: struct mpfr_float_backend : public detail::mpfr_float_imp Chris@16: { Chris@16: mpfr_float_backend() : detail::mpfr_float_imp() {} Chris@16: mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp(o) {} Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@101: mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp(static_cast&&>(o)) {} Chris@16: #endif Chris@16: template Chris@16: mpfr_float_backend(const mpfr_float_backend& val, typename enable_if_c::type* = 0) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: explicit mpfr_float_backend(const mpfr_float_backend& val, typename disable_if_c::type* = 0) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: mpfr_float_backend(const gmp_float& val, typename enable_if_c::type* = 0) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set_f(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: mpfr_float_backend(const gmp_float& val, typename disable_if_c::type* = 0) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set_f(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const gmp_int& val) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set_z(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const gmp_rational& val) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set_q(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const mpfr_t val) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set(this->m_data, val, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const mpf_t val) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set_f(this->m_data, val, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const mpz_t val) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set_z(this->m_data, val, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const mpq_t val) Chris@16: : detail::mpfr_float_imp() Chris@16: { Chris@16: mpfr_set_q(this->m_data, val, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpfr_float_backend& o) Chris@16: { Chris@16: *static_cast*>(this) = static_cast const&>(o); Chris@16: return *this; Chris@16: } Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT Chris@16: { Chris@16: *static_cast*>(this) = static_cast&&>(o); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: template Chris@16: mpfr_float_backend& operator=(const V& v) Chris@16: { Chris@16: *static_cast*>(this) = v; Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpfr_t val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); Chris@16: mpfr_set(this->m_data, val, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpf_t val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); Chris@16: mpfr_set_f(this->m_data, val, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpz_t val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); Chris@16: mpfr_set_z(this->m_data, val, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpq_t val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); Chris@16: mpfr_set_q(this->m_data, val, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: // We don't change our precision here, this is a fixed precision type: Chris@16: template Chris@16: mpfr_float_backend& operator=(const mpfr_float_backend& val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); Chris@16: mpfr_set(this->m_data, val.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: mpfr_float_backend& operator=(const gmp_float& val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); Chris@16: mpfr_set_f(this->m_data, val.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const gmp_int& val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); Chris@16: mpfr_set_z(this->m_data, val.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const gmp_rational& val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); Chris@16: mpfr_set_q(this->m_data, val.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic> Chris@16: { Chris@16: mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {} Chris@16: mpfr_float_backend(const mpfr_t val) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val)) Chris@16: { Chris@16: mpfr_set(this->m_data, val, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const mpf_t val) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val)) Chris@16: { Chris@16: mpfr_set_f(this->m_data, val, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const mpz_t val) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>() Chris@16: { Chris@16: mpfr_set_z(this->m_data, val, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const mpq_t val) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>() Chris@16: { Chris@16: mpfr_set_q(this->m_data, val, GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {} Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast&&>(o)) {} Chris@16: #endif Chris@16: mpfr_float_backend(const mpfr_float_backend& o, unsigned digits10) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>(digits10) Chris@16: { Chris@16: *this = o; Chris@16: } Chris@16: template Chris@16: mpfr_float_backend(const mpfr_float_backend& val) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val.data())) Chris@16: { Chris@16: mpfr_set(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: mpfr_float_backend(const gmp_float& val) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val.data())) Chris@16: { Chris@16: mpfr_set_f(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const gmp_int& val) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>() Chris@16: { Chris@16: mpfr_set_z(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: mpfr_float_backend(const gmp_rational& val) Chris@16: : detail::mpfr_float_imp<0, allocate_dynamic>() Chris@16: { Chris@16: mpfr_set_q(this->m_data, val.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: mpfr_float_backend& operator=(const mpfr_float_backend& o) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, mpfr_get_prec(o.data())); Chris@16: else Chris@16: mpfr_set_prec(this->m_data, mpfr_get_prec(o.data())); Chris@16: mpfr_set(this->m_data, o.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT Chris@16: { Chris@16: *static_cast*>(this) = static_cast &&>(o); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: template Chris@16: mpfr_float_backend& operator=(const V& v) Chris@16: { Chris@16: *static_cast*>(this) = v; Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpfr_t val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, mpfr_get_prec(val)); Chris@16: else Chris@16: mpfr_set_prec(this->m_data, mpfr_get_prec(val)); Chris@16: mpfr_set(this->m_data, val, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpf_t val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, mpf_get_prec(val)); Chris@16: else Chris@16: mpfr_set_prec(this->m_data, mpf_get_prec(val)); Chris@16: mpfr_set_f(this->m_data, val, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpz_t val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); Chris@16: mpfr_set_z(this->m_data, val, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const mpq_t val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); Chris@16: mpfr_set_q(this->m_data, val, GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: mpfr_float_backend& operator=(const mpfr_float_backend& val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, mpfr_get_prec(val.data())); Chris@16: else Chris@16: mpfr_set_prec(this->m_data, mpfr_get_prec(val.data())); Chris@16: mpfr_set(this->m_data, val.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: mpfr_float_backend& operator=(const gmp_float& val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, mpf_get_prec(val.data())); Chris@16: else Chris@16: mpfr_set_prec(this->m_data, mpf_get_prec(val.data())); Chris@16: mpfr_set_f(this->m_data, val.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const gmp_int& val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); Chris@16: mpfr_set_z(this->m_data, val.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: mpfr_float_backend& operator=(const gmp_rational& val) Chris@16: { Chris@16: if(this->m_data[0]._mpfr_d == 0) Chris@16: mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); Chris@16: mpfr_set_q(this->m_data, val.data(), GMP_RNDN); Chris@16: return *this; Chris@16: } Chris@16: static unsigned default_precision() BOOST_NOEXCEPT Chris@16: { Chris@16: return get_default_precision(); Chris@16: } Chris@16: static void default_precision(unsigned v) BOOST_NOEXCEPT Chris@16: { Chris@16: get_default_precision() = v; Chris@16: } Chris@16: unsigned precision()const BOOST_NOEXCEPT Chris@16: { Chris@16: return multiprecision::detail::digits2_2_10(mpfr_get_prec(this->m_data)); Chris@16: } Chris@16: void precision(unsigned digits10) BOOST_NOEXCEPT Chris@16: { Chris@16: mpfr_prec_round(this->m_data, multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: inline typename enable_if, bool>::type eval_eq(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT Chris@16: { Chris@16: return a.compare(b) == 0; Chris@16: } Chris@16: template Chris@16: inline typename enable_if, bool>::type eval_lt(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT Chris@16: { Chris@16: return a.compare(b) < 0; Chris@16: } Chris@16: template Chris@16: inline typename enable_if, bool>::type eval_gt(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT Chris@16: { Chris@16: return a.compare(b) > 0; Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_add(mpfr_float_backend& result, const mpfr_float_backend& o) Chris@16: { Chris@16: mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_subtract(mpfr_float_backend& result, const mpfr_float_backend& o) Chris@16: { Chris@16: mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_multiply(mpfr_float_backend& result, const mpfr_float_backend& o) Chris@16: { Chris@16: if((void*)&o == (void*)&result) Chris@16: mpfr_sqr(result.data(), o.data(), GMP_RNDN); Chris@16: else Chris@16: mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_divide(mpfr_float_backend& result, const mpfr_float_backend& o) Chris@16: { Chris@16: mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_add(mpfr_float_backend& result, unsigned long i) Chris@16: { Chris@16: mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_subtract(mpfr_float_backend& result, unsigned long i) Chris@16: { Chris@16: mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_multiply(mpfr_float_backend& result, unsigned long i) Chris@16: { Chris@16: mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_divide(mpfr_float_backend& result, unsigned long i) Chris@16: { Chris@16: mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_add(mpfr_float_backend& result, long i) Chris@16: { Chris@16: if(i > 0) Chris@16: mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN); Chris@16: else Chris@101: mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_subtract(mpfr_float_backend& result, long i) Chris@16: { Chris@16: if(i > 0) Chris@16: mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN); Chris@16: else Chris@101: mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_multiply(mpfr_float_backend& result, long i) Chris@16: { Chris@101: mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); Chris@16: if(i < 0) Chris@16: mpfr_neg(result.data(), result.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_divide(mpfr_float_backend& result, long i) Chris@16: { Chris@101: mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); Chris@16: if(i < 0) Chris@16: mpfr_neg(result.data(), result.data(), GMP_RNDN); Chris@16: } Chris@16: // Chris@16: // Specialised 3 arg versions of the basic operators: Chris@16: // Chris@16: template Chris@16: inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) Chris@16: { Chris@16: mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) Chris@16: { Chris@16: mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, long y) Chris@16: { Chris@16: if(y < 0) Chris@101: mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); Chris@16: else Chris@16: mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_add(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) Chris@16: { Chris@16: mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_add(mpfr_float_backend& a, long x, const mpfr_float_backend& y) Chris@16: { Chris@16: if(x < 0) Chris@16: { Chris@101: mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN); Chris@16: mpfr_neg(a.data(), a.data(), GMP_RNDN); Chris@16: } Chris@16: else Chris@16: mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) Chris@16: { Chris@16: mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) Chris@16: { Chris@16: mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, long y) Chris@16: { Chris@16: if(y < 0) Chris@101: mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); Chris@16: else Chris@16: mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_subtract(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) Chris@16: { Chris@16: mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_subtract(mpfr_float_backend& a, long x, const mpfr_float_backend& y) Chris@16: { Chris@16: if(x < 0) Chris@16: { Chris@101: mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN); Chris@16: mpfr_neg(a.data(), a.data(), GMP_RNDN); Chris@16: } Chris@16: else Chris@16: mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) Chris@16: { Chris@16: if((void*)&x == (void*)&y) Chris@16: mpfr_sqr(a.data(), x.data(), GMP_RNDN); Chris@16: else Chris@16: mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) Chris@16: { Chris@16: mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, long y) Chris@16: { Chris@16: if(y < 0) Chris@16: { Chris@101: mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); Chris@16: a.negate(); Chris@16: } Chris@16: else Chris@16: mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_multiply(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) Chris@16: { Chris@16: mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_multiply(mpfr_float_backend& a, long x, const mpfr_float_backend& y) Chris@16: { Chris@16: if(x < 0) Chris@16: { Chris@101: mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN); Chris@16: mpfr_neg(a.data(), a.data(), GMP_RNDN); Chris@16: } Chris@16: else Chris@16: mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) Chris@16: { Chris@16: mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) Chris@16: { Chris@16: mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, long y) Chris@16: { Chris@16: if(y < 0) Chris@16: { Chris@101: mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); Chris@16: a.negate(); Chris@16: } Chris@16: else Chris@16: mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_divide(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) Chris@16: { Chris@16: mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_divide(mpfr_float_backend& a, long x, const mpfr_float_backend& y) Chris@16: { Chris@16: if(x < 0) Chris@16: { Chris@101: mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN); Chris@16: mpfr_neg(a.data(), a.data(), GMP_RNDN); Chris@16: } Chris@16: else Chris@16: mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool eval_is_zero(const mpfr_float_backend& val) BOOST_NOEXCEPT Chris@16: { Chris@16: return 0 != mpfr_zero_p(val.data()); Chris@16: } Chris@16: template Chris@16: inline int eval_get_sign(const mpfr_float_backend& val) BOOST_NOEXCEPT Chris@16: { Chris@16: return mpfr_sgn(val.data()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_convert_to(unsigned long* result, const mpfr_float_backend& val) Chris@16: { Chris@16: if(mpfr_nan_p(val.data())) Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); Chris@16: } Chris@16: *result = mpfr_get_ui(val.data(), GMP_RNDZ); Chris@16: } Chris@16: template Chris@16: inline void eval_convert_to(long* result, const mpfr_float_backend& val) Chris@16: { Chris@16: if(mpfr_nan_p(val.data())) Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); Chris@16: } Chris@16: *result = mpfr_get_si(val.data(), GMP_RNDZ); Chris@16: } Chris@16: #ifdef _MPFR_H_HAVE_INTMAX_T Chris@16: template Chris@16: inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend& val) Chris@16: { Chris@16: if(mpfr_nan_p(val.data())) Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); Chris@16: } Chris@16: *result = mpfr_get_uj(val.data(), GMP_RNDZ); Chris@16: } Chris@16: template Chris@16: inline void eval_convert_to(long long* result, const mpfr_float_backend& val) Chris@16: { Chris@16: if(mpfr_nan_p(val.data())) Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); Chris@16: } Chris@16: *result = mpfr_get_sj(val.data(), GMP_RNDZ); Chris@16: } Chris@16: #endif Chris@16: template Chris@16: inline void eval_convert_to(double* result, const mpfr_float_backend& val) BOOST_NOEXCEPT Chris@16: { Chris@16: *result = mpfr_get_d(val.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_convert_to(long double* result, const mpfr_float_backend& val) BOOST_NOEXCEPT Chris@16: { Chris@16: *result = mpfr_get_ld(val.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: // Chris@16: // Native non-member operations: Chris@16: // Chris@16: template Chris@16: inline void eval_sqrt(mpfr_float_backend& result, const mpfr_float_backend& val) Chris@16: { Chris@16: mpfr_sqrt(result.data(), val.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_abs(mpfr_float_backend& result, const mpfr_float_backend& val) Chris@16: { Chris@16: mpfr_abs(result.data(), val.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_fabs(mpfr_float_backend& result, const mpfr_float_backend& val) Chris@16: { Chris@16: mpfr_abs(result.data(), val.data(), GMP_RNDN); Chris@16: } Chris@16: template Chris@16: inline void eval_ceil(mpfr_float_backend& result, const mpfr_float_backend& val) Chris@16: { Chris@16: mpfr_ceil(result.data(), val.data()); Chris@16: } Chris@16: template Chris@16: inline void eval_floor(mpfr_float_backend& result, const mpfr_float_backend& val) Chris@16: { Chris@16: mpfr_floor(result.data(), val.data()); Chris@16: } Chris@16: template Chris@16: inline void eval_trunc(mpfr_float_backend& result, const mpfr_float_backend& val) Chris@16: { Chris@16: if(0 == mpfr_number_p(val.data())) Chris@16: { Chris@16: result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number >(val), number >(val), boost::math::policies::policy<>()).backend(); Chris@16: return; Chris@16: } Chris@16: mpfr_trunc(result.data(), val.data()); Chris@16: } Chris@16: template Chris@16: inline void eval_ldexp(mpfr_float_backend& result, const mpfr_float_backend& val, long e) Chris@16: { Chris@16: if(e > 0) Chris@16: mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN); Chris@16: else if(e < 0) Chris@16: mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN); Chris@16: else Chris@16: result = val; Chris@16: } Chris@16: template Chris@16: inline void eval_frexp(mpfr_float_backend& result, const mpfr_float_backend& val, int* e) Chris@16: { Chris@16: long v; Chris@16: mpfr_get_d_2exp(&v, val.data(), GMP_RNDN); Chris@16: *e = v; Chris@16: eval_ldexp(result, val, -v); Chris@16: } Chris@16: template Chris@16: inline void eval_frexp(mpfr_float_backend& result, const mpfr_float_backend& val, long* e) Chris@16: { Chris@16: mpfr_get_d_2exp(e, val.data(), GMP_RNDN); Chris@16: return eval_ldexp(result, val, -*e); Chris@16: } Chris@16: Chris@16: template Chris@16: inline int eval_fpclassify(const mpfr_float_backend& val) BOOST_NOEXCEPT Chris@16: { Chris@16: return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL; Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const mpfr_float_backend& e) Chris@16: { Chris@16: mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: // Chris@16: // The enable_if usage below doesn't work with msvc - but only when Chris@16: // certain other enable_if usages are defined first. It's a capricious Chris@16: // and rather annoying compiler bug in other words.... Chris@16: // Chris@16: # define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10) && Chris@16: #else Chris@16: #define BOOST_MP_ENABLE_IF_WORKAROUND Chris@16: #endif Chris@16: Chris@16: template Chris@16: inline typename enable_if, mpl::bool_ > >::type Chris@16: eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const Integer& e) Chris@16: { Chris@16: mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename enable_if, mpl::bool_ > >::type Chris@16: eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const Integer& e) Chris@16: { Chris@16: mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN); Chris@16: } Chris@16: Chris@16: #undef BOOST_MP_ENABLE_IF_WORKAROUND Chris@16: Chris@16: template Chris@16: inline void eval_exp(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_exp(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_log(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_log(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_log10(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_log10(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_sin(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_sin(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_cos(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_cos(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_tan(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_tan(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_asin(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_asin(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_acos(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_acos(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_atan(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_atan(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_atan2(mpfr_float_backend& result, const mpfr_float_backend& arg1, const mpfr_float_backend& arg2) Chris@16: { Chris@16: mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_sinh(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_sinh(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_cosh(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_cosh(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void eval_tanh(mpfr_float_backend& result, const mpfr_float_backend& arg) Chris@16: { Chris@16: mpfr_tanh(result.data(), arg.data(), GMP_RNDN); Chris@16: } Chris@16: Chris@16: } // namespace backends Chris@16: Chris@16: #ifdef BOOST_NO_SFINAE_EXPR Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: template Chris@16: struct is_explicitly_convertible, backends::mpfr_float_backend > : public mpl::true_ {}; Chris@16: Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: template<> Chris@16: struct number_category >::type> : public mpl::int_{}; Chris@16: Chris@16: using boost::multiprecision::backends::mpfr_float_backend; Chris@16: Chris@16: typedef number > mpfr_float_50; Chris@16: typedef number > mpfr_float_100; Chris@16: typedef number > mpfr_float_500; Chris@16: typedef number > mpfr_float_1000; Chris@16: typedef number > mpfr_float; Chris@16: Chris@16: typedef number > static_mpfr_float_50; Chris@16: typedef number > static_mpfr_float_100; Chris@16: Chris@16: } // namespace multiprecision Chris@16: Chris@16: namespace math{ Chris@16: Chris@16: namespace tools{ Chris@16: Chris@16: template <> Chris@16: inline int digits() Chris@16: { Chris@16: return boost::multiprecision::backends::detail::get_default_precision(); Chris@16: } Chris@16: template <> Chris@16: inline int digits, boost::multiprecision::et_off> >() Chris@16: { Chris@16: return boost::multiprecision::backends::detail::get_default_precision(); Chris@16: } Chris@16: Chris@16: } // namespace tools Chris@16: Chris@16: namespace constants{ namespace detail{ Chris@16: Chris@16: template struct constant_pi; Chris@16: template struct constant_ln_two; Chris@16: template struct constant_euler; Chris@16: template struct constant_catalan; Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: template Chris@16: struct mpfr_constant_initializer Chris@16: { Chris@16: static void force_instantiate() Chris@16: { Chris@16: init.force_instantiate(); Chris@16: } Chris@16: private: Chris@16: struct initializer Chris@16: { Chris@16: initializer() Chris@16: { Chris@16: T::get(mpl::int_()); Chris@16: } Chris@16: void force_instantiate()const{} Chris@16: }; Chris@16: static const initializer init; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename mpfr_constant_initializer::initializer const mpfr_constant_initializer::init; Chris@16: Chris@16: } Chris@16: Chris@16: template Chris@16: struct constant_pi, ExpressionTemplates> > Chris@16: { Chris@16: typedef boost::multiprecision::number, ExpressionTemplates> result_type; Chris@16: template Chris@16: static inline const result_type& get(const mpl::int_&) Chris@16: { Chris@16: detail::mpfr_constant_initializer, ExpressionTemplates> >, N>::force_instantiate(); Chris@16: static result_type result; Chris@16: static bool has_init = false; Chris@16: if(!has_init) Chris@16: { Chris@16: mpfr_const_pi(result.backend().data(), GMP_RNDN); Chris@16: has_init = true; Chris@16: } Chris@16: return result; Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct constant_ln_two, ExpressionTemplates> > Chris@16: { Chris@16: typedef boost::multiprecision::number, ExpressionTemplates> result_type; Chris@16: template Chris@16: static inline const result_type& get(const mpl::int_&) Chris@16: { Chris@16: detail::mpfr_constant_initializer, ExpressionTemplates> >, N>::force_instantiate(); Chris@16: static result_type result; Chris@16: static bool init = false; Chris@16: if(!init) Chris@16: { Chris@16: mpfr_const_log2(result.backend().data(), GMP_RNDN); Chris@16: init = true; Chris@16: } Chris@16: return result; Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct constant_euler, ExpressionTemplates> > Chris@16: { Chris@16: typedef boost::multiprecision::number, ExpressionTemplates> result_type; Chris@16: template Chris@16: static inline const result_type& get(const mpl::int_&) Chris@16: { Chris@16: detail::mpfr_constant_initializer, ExpressionTemplates> >, N>::force_instantiate(); Chris@16: static result_type result; Chris@16: static bool init = false; Chris@16: if(!init) Chris@16: { Chris@16: mpfr_const_euler(result.backend().data(), GMP_RNDN); Chris@16: init = true; Chris@16: } Chris@16: return result; Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct constant_catalan, ExpressionTemplates> > Chris@16: { Chris@16: typedef boost::multiprecision::number, ExpressionTemplates> result_type; Chris@16: template Chris@16: static inline const result_type& get(const mpl::int_&) Chris@16: { Chris@16: detail::mpfr_constant_initializer, ExpressionTemplates> >, N>::force_instantiate(); Chris@16: static result_type result; Chris@16: static bool init = false; Chris@16: if(!init) Chris@16: { Chris@16: mpfr_const_catalan(result.backend().data(), GMP_RNDN); Chris@16: init = true; Chris@16: } Chris@16: return result; Chris@16: } Chris@16: }; Chris@16: Chris@16: }} // namespaces Chris@16: Chris@16: }} // namespaces Chris@16: Chris@16: namespace std{ Chris@16: Chris@16: // Chris@16: // numeric_limits [partial] specializations for the types declared in this header: Chris@16: // Chris@16: template Chris@16: class numeric_limits, ExpressionTemplates> > Chris@16: { Chris@16: typedef boost::multiprecision::number, ExpressionTemplates> number_type; Chris@16: public: Chris@16: BOOST_STATIC_CONSTEXPR bool is_specialized = true; Chris@16: static number_type (min)() Chris@16: { Chris@16: initializer.do_nothing(); Chris@16: static std::pair value; Chris@16: if(!value.first) Chris@16: { Chris@16: value.first = true; Chris@16: value.second = 0.5; Chris@16: mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin(), GMP_RNDN); Chris@16: } Chris@16: return value.second; Chris@16: } Chris@16: static number_type (max)() Chris@16: { Chris@16: initializer.do_nothing(); Chris@16: static std::pair value; Chris@16: if(!value.first) Chris@16: { Chris@16: value.first = true; Chris@16: value.second = 0.5; Chris@16: mpfr_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax(), GMP_RNDN); Chris@16: } Chris@16: return value.second; Chris@16: } Chris@16: BOOST_STATIC_CONSTEXPR number_type lowest() Chris@16: { Chris@16: return -(max)(); Chris@16: } Chris@16: BOOST_STATIC_CONSTEXPR int digits = static_cast((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1)); Chris@16: BOOST_STATIC_CONSTEXPR int digits10 = Digits10; Chris@16: // Is this really correct??? Chris@16: BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2; Chris@16: BOOST_STATIC_CONSTEXPR bool is_signed = true; Chris@16: BOOST_STATIC_CONSTEXPR bool is_integer = false; Chris@16: BOOST_STATIC_CONSTEXPR bool is_exact = false; Chris@16: BOOST_STATIC_CONSTEXPR int radix = 2; Chris@16: static number_type epsilon() Chris@16: { Chris@16: initializer.do_nothing(); Chris@16: static std::pair value; Chris@16: if(!value.first) Chris@16: { Chris@16: value.first = true; Chris@16: value.second = 1; Chris@16: mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits::digits - 1, GMP_RNDN); Chris@16: } Chris@16: return value.second; Chris@16: } Chris@16: // What value should this be???? Chris@16: static number_type round_error() Chris@16: { Chris@16: // returns epsilon/2 Chris@16: initializer.do_nothing(); Chris@16: static std::pair value; Chris@16: if(!value.first) Chris@16: { Chris@16: value.first = true; Chris@16: value.second = 1; Chris@16: mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), 1, GMP_RNDN); Chris@16: } Chris@16: return value.second; Chris@16: } Chris@16: BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT; Chris@16: BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L; Chris@16: BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT; Chris@16: BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L; Chris@16: BOOST_STATIC_CONSTEXPR bool has_infinity = true; Chris@16: BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true; Chris@16: BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; Chris@16: BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; Chris@16: BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; Chris@16: static number_type infinity() Chris@16: { Chris@16: // returns epsilon/2 Chris@16: initializer.do_nothing(); Chris@16: static std::pair value; Chris@16: if(!value.first) Chris@16: { Chris@16: value.first = true; Chris@16: value.second = 1; Chris@16: mpfr_set_inf(value.second.backend().data(), 1); Chris@16: } Chris@16: return value.second; Chris@16: } Chris@16: static number_type quiet_NaN() Chris@16: { Chris@16: // returns epsilon/2 Chris@16: initializer.do_nothing(); Chris@16: static std::pair value; Chris@16: if(!value.first) Chris@16: { Chris@16: value.first = true; Chris@16: value.second = 1; Chris@16: mpfr_set_nan(value.second.backend().data()); Chris@16: } Chris@16: return value.second; Chris@16: } Chris@16: BOOST_STATIC_CONSTEXPR number_type signaling_NaN() Chris@16: { Chris@16: return number_type(0); Chris@16: } Chris@16: BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); } Chris@16: BOOST_STATIC_CONSTEXPR bool is_iec559 = false; Chris@16: BOOST_STATIC_CONSTEXPR bool is_bounded = true; Chris@16: BOOST_STATIC_CONSTEXPR bool is_modulo = false; Chris@16: BOOST_STATIC_CONSTEXPR bool traps = true; Chris@16: BOOST_STATIC_CONSTEXPR bool tinyness_before = false; Chris@16: BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest; Chris@16: Chris@16: private: Chris@16: struct data_initializer Chris@16: { Chris@16: data_initializer() Chris@16: { Chris@16: std::numeric_limits > >::epsilon(); Chris@16: std::numeric_limits > >::round_error(); Chris@16: (std::numeric_limits > >::min)(); Chris@16: (std::numeric_limits > >::max)(); Chris@16: std::numeric_limits > >::infinity(); Chris@16: std::numeric_limits > >::quiet_NaN(); Chris@16: } Chris@16: void do_nothing()const{} Chris@16: }; Chris@16: static const data_initializer initializer; Chris@16: }; Chris@16: Chris@16: template Chris@16: const typename numeric_limits, ExpressionTemplates> >::data_initializer numeric_limits, ExpressionTemplates> >::initializer; Chris@16: Chris@16: #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION Chris@16: Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits10; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::max_digits10; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_signed; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_integer; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_exact; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::radix; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::min_exponent; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::min_exponent10; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::max_exponent; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::max_exponent10; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_infinity; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_quiet_NaN; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_signaling_NaN; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits, ExpressionTemplates> >::has_denorm; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_denorm_loss; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_iec559; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_bounded; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_modulo; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::traps; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::tinyness_before; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits, ExpressionTemplates> >::round_style; Chris@16: Chris@16: #endif Chris@16: Chris@16: Chris@16: template Chris@16: class numeric_limits, ExpressionTemplates> > Chris@16: { Chris@16: typedef boost::multiprecision::number, ExpressionTemplates> number_type; Chris@16: public: Chris@16: BOOST_STATIC_CONSTEXPR bool is_specialized = false; Chris@16: static number_type (min)() { return number_type(0); } Chris@16: static number_type (max)() { return number_type(0); } Chris@16: static number_type lowest() { return number_type(0); } Chris@16: BOOST_STATIC_CONSTEXPR int digits = 0; Chris@16: BOOST_STATIC_CONSTEXPR int digits10 = 0; Chris@16: BOOST_STATIC_CONSTEXPR int max_digits10 = 0; Chris@16: BOOST_STATIC_CONSTEXPR bool is_signed = false; Chris@16: BOOST_STATIC_CONSTEXPR bool is_integer = false; Chris@16: BOOST_STATIC_CONSTEXPR bool is_exact = false; Chris@16: BOOST_STATIC_CONSTEXPR int radix = 0; Chris@16: static number_type epsilon() { return number_type(0); } Chris@16: static number_type round_error() { return number_type(0); } Chris@16: BOOST_STATIC_CONSTEXPR int min_exponent = 0; Chris@16: BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; Chris@16: BOOST_STATIC_CONSTEXPR int max_exponent = 0; Chris@16: BOOST_STATIC_CONSTEXPR int max_exponent10 = 0; Chris@16: BOOST_STATIC_CONSTEXPR bool has_infinity = false; Chris@16: BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false; Chris@16: BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; Chris@16: BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; Chris@16: BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; Chris@16: static number_type infinity() { return number_type(0); } Chris@16: static number_type quiet_NaN() { return number_type(0); } Chris@16: static number_type signaling_NaN() { return number_type(0); } Chris@16: static number_type denorm_min() { return number_type(0); } Chris@16: BOOST_STATIC_CONSTEXPR bool is_iec559 = false; Chris@16: BOOST_STATIC_CONSTEXPR bool is_bounded = false; Chris@16: BOOST_STATIC_CONSTEXPR bool is_modulo = false; Chris@16: BOOST_STATIC_CONSTEXPR bool traps = false; Chris@16: BOOST_STATIC_CONSTEXPR bool tinyness_before = false; Chris@16: BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero; Chris@16: }; Chris@16: Chris@16: #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION Chris@16: Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits10; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::max_digits10; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_signed; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_integer; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_exact; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::radix; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::min_exponent; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::min_exponent10; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::max_exponent; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::max_exponent10; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_infinity; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_quiet_NaN; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_signaling_NaN; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits, ExpressionTemplates> >::has_denorm; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_denorm_loss; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_iec559; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_bounded; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_modulo; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::traps; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::tinyness_before; Chris@16: template Chris@16: BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits, ExpressionTemplates> >::round_style; Chris@16: Chris@16: #endif Chris@16: } // namespace std Chris@16: #endif