From e28b1be017512d09b5cf2be205c2018300e58446 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 22 Oct 2015 10:11:16 +0100 Subject: [PATCH] Fix order-of-evalution bug in bitmask code. Allow mpfr_float to be used with Boost.Math by adding needed specializations. --- include/boost/multiprecision/mpfi.hpp | 2 +- include/boost/multiprecision/mpfr.hpp | 44 +++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/include/boost/multiprecision/mpfi.hpp b/include/boost/multiprecision/mpfi.hpp index 35e47b53..66a23cab 100644 --- a/include/boost/multiprecision/mpfi.hpp +++ b/include/boost/multiprecision/mpfi.hpp @@ -125,7 +125,7 @@ struct mpfi_float_imp { 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::digits - 1) - 1) << 1) | 1u); + boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits::digits - 1)) - 1) << 1) | 1u); unsigned shift = 0; mpfi_t t; mpfi_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index 80b34a39..fde558be 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -131,7 +131,7 @@ struct mpfr_float_imp { 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::digits - 1) - 1) << 1) | 1uLL); + boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits::digits - 1)) - 1) << 1) | 1uLL); unsigned shift = 0; mpfr_t t; mpfr_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); @@ -419,7 +419,7 @@ struct mpfr_float_imp #else mpfr_float_imp& operator = (boost::ulong_long_type i) { - boost::ulong_long_type mask = (((1uLL << (std::numeric_limits::digits - 1) - 1) << 1) | 1uL); + boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits::digits - 1)) - 1) << 1) | 1uL); unsigned shift = 0; mpfr_t t; mp_limb_t t_limbs[limb_count]; @@ -1470,6 +1470,46 @@ inline int digits +inline boost::multiprecision::mpfr_float + max_value() +{ + 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 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::et_off> + max_value, boost::multiprecision::et_off> >() +{ + boost::multiprecision::number, 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::et_off> + min_value, boost::multiprecision::et_off> >() +{ + boost::multiprecision::number, 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; +} + } // namespace tools namespace constants{ namespace detail{