Add ldexp and frexp.

[SVN r73612]
This commit is contained in:
John Maddock
2011-08-08 17:13:50 +00:00
parent 41bee8c142
commit 53d0691ac9
2 changed files with 39 additions and 0 deletions

View File

@@ -413,6 +413,30 @@ big_number<gmp_real<Digits10> > trunc(const big_number<gmp_real<Digits10> >& val
mpf_trunc(result.backend().data(), val.backend().data());
return result;
}
template <unsigned Digits10>
big_number<gmp_real<Digits10> > ldexp(const big_number<gmp_real<Digits10> >& val, long e)
{
big_number<gmp_real<Digits10> > result;
if(e > 0)
mpf_mul_2exp(result.backend().data(), val.backend().data(), e);
else if(e < 0)
mpf_div_2exp(result.backend().data(), val.backend().data(), -e);
return result;
}
template <unsigned Digits10>
big_number<gmp_real<Digits10> > frexp(const big_number<gmp_real<Digits10> >& val, int* e)
{
long v;
mpf_get_d_2exp(&v, val.backend().data());
*e = v;
return ldexp(val, -v);
}
template <unsigned Digits10>
big_number<gmp_real<Digits10> > frexp(const big_number<gmp_real<Digits10> >& val, long* e)
{
mpf_get_d_2exp(e, val.backend().data());
return ldexp(val, -*v);
}
struct gmp_int
{

View File

@@ -85,6 +85,21 @@ void test_real_ops(const boost::mpl::true_&)
BOOST_TEST(ceil(Real(-5) / 2) == -2);
BOOST_TEST(trunc(Real(5) / 2) == 2);
BOOST_TEST(trunc(Real(-5) / 2) == -2);
//
// ldexp and frexp, these pretty much have to implemented by each backend:
//
BOOST_TEST(ldexp(Real(2), 5) == 64);
BOOST_TEST(ldexp(Real(2), -5) == Real(2) / 32);
Real v(512);
int exp;
Real r = frexp(v, &exp);
BOOST_TEST(r == 0.5);
BOOST_TEST(exp == 10);
v = 1 / v;
r = frexp(v, &exp);
BOOST_TEST(r == 0.5);
BOOST_TEST(exp == -8);
}
template <class Real, class Num>