diff --git a/include/boost/math/big_number/gmp.hpp b/include/boost/math/big_number/gmp.hpp index 374c7594..aaa5a068 100644 --- a/include/boost/math/big_number/gmp.hpp +++ b/include/boost/math/big_number/gmp.hpp @@ -413,6 +413,30 @@ big_number > trunc(const big_number >& val mpf_trunc(result.backend().data(), val.backend().data()); return result; } +template +big_number > ldexp(const big_number >& val, long e) +{ + big_number > 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 +big_number > frexp(const big_number >& val, int* e) +{ + long v; + mpf_get_d_2exp(&v, val.backend().data()); + *e = v; + return ldexp(val, -v); +} +template +big_number > frexp(const big_number >& val, long* e) +{ + mpf_get_d_2exp(e, val.backend().data()); + return ldexp(val, -*v); +} struct gmp_int { diff --git a/math/test/test_arithmetic.cpp b/math/test/test_arithmetic.cpp index e09d7f59..fa2fc9c6 100644 --- a/math/test/test_arithmetic.cpp +++ b/math/test/test_arithmetic.cpp @@ -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