Fix frexp for mpfr:

Make sure we call the correct API, add motivating test case.
This commit is contained in:
jzmaddock
2020-08-12 11:43:55 +01:00
parent 0a1110ef3d
commit 596259874b
3 changed files with 51 additions and 5 deletions
+23 -5
View File
@@ -1366,16 +1366,34 @@ inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const
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);
if (mpfr_zero_p(val.data()))
{
*e = 0;
result = val;
return;
}
mp_exp_t v = mpfr_get_exp(val.data());
*e = v;
eval_ldexp(result, val, -v);
if (v)
eval_ldexp(result, val, -v);
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, long* e)
{
mpfr_get_d_2exp(e, val.data(), GMP_RNDN);
return eval_ldexp(result, val, -*e);
if (mpfr_zero_p(val.data()))
{
*e = 0;
result = val;
return;
}
mp_exp_t v = mpfr_get_exp(val.data());
*e = v;
if(v)
eval_ldexp(result, val, -v);
else
result = val;
}
template <unsigned Digits10, mpfr_allocation_type AllocateType>
+1
View File
@@ -1014,6 +1014,7 @@ test-suite misc :
[ run git_issue_167.cpp ]
[ run git_issue_175.cpp ]
[ run git_issue_248.cpp ]
[ run git_issue_265.cpp : : : [ check-target-builds ../config//has_mpfr : <source>gmp <source>mpfr : <build>no ] ]
[ compile git_issue_98.cpp :
[ check-target-builds ../config//has_float128 : <define>TEST_FLOAT128 <source>quadmath : ]
[ check-target-builds ../config//has_gmp : <define>TEST_GMP <source>gmp : ]
+27
View File
@@ -0,0 +1,27 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2020 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)
#include <boost/multiprecision/mpfr.hpp>
#include <boost/math/special_functions/next.hpp>
#include "test.hpp"
using namespace boost::multiprecision;
int main()
{
mpfr_float_50 half = 0.5;
mpfr_float_50 under_half = boost::math::float_prior(half);
BOOST_CHECK_NE(half, under_half);
int e1, e2;
mpfr_float_50 norm1, norm2;
norm1 = frexp(half, &e1);
norm2 = frexp(under_half, &e2);
BOOST_CHECK_EQUAL(norm1, half);
BOOST_CHECK_EQUAL(e1, 0);
BOOST_CHECK_GT(1, norm2);
BOOST_CHECK_LE(0.5, norm2);
BOOST_CHECK_EQUAL(e2, -1);
return boost::report_errors();
}