Fix order-of-evalution bug in bitmask code.

Allow mpfr_float to be used with Boost.Math by adding needed specializations.
This commit is contained in:
jzmaddock
2015-10-22 10:11:16 +01:00
parent dde9570d11
commit e28b1be017
2 changed files with 43 additions and 3 deletions

View File

@@ -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<unsigned long>::digits - 1) - 1) << 1) | 1u);
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))));

View File

@@ -131,7 +131,7 @@ struct mpfr_float_imp<digits10, allocate_dynamic>
{
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);
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))));
@@ -419,7 +419,7 @@ struct mpfr_float_imp<digits10, allocate_stack>
#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);
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];
@@ -1470,6 +1470,46 @@ inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_floa
return boost::multiprecision::backends::detail::get_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;
}
} // namespace tools
namespace constants{ namespace detail{