|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r86335 - in sandbox/multiprecision.cpp_bin_float: boost/multiprecision boost/multiprecision/cpp_bin_float libs/multiprecision/doc libs/multiprecision/doc/html libs/multiprecision/doc/html/boost_multiprecision libs/multiprecision/doc/html/boost_multiprecision/tut/limits libs/multiprecision/doc/html/boost_multiprecision/tut/misc libs/multiprecision/test
From: john_at_[hidden]
Date: 2013-10-16 13:49:10
Author: johnmaddock
Date: 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013)
New Revision: 86335
URL: http://svn.boost.org/trac/boost/changeset/86335
Log:
Add support for custom exponent types and ranges.
Add typedefs which match built in floating point types.
Fix a couple of doc typos.
Text files modified:
sandbox/multiprecision.cpp_bin_float/boost/multiprecision/cpp_bin_float.hpp | 706 ++++++++++++++++++++++-----------------
sandbox/multiprecision.cpp_bin_float/boost/multiprecision/cpp_bin_float/io.hpp | 130 +++---
sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/ref.html | 6
sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut.html | 1
sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut/limits/limits32.html | 6
sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut/misc/visualizers.html | 2
sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/index.html | 3
sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/multiprecision.qbk | 6
sandbox/multiprecision.cpp_bin_float/libs/multiprecision/test/test_arithmetic_cpp_bin_float_1.cpp | 4
9 files changed, 488 insertions(+), 376 deletions(-)
Modified: sandbox/multiprecision.cpp_bin_float/boost/multiprecision/cpp_bin_float.hpp
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/boost/multiprecision/cpp_bin_float.hpp Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/boost/multiprecision/cpp_bin_float.hpp 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -19,7 +19,12 @@
digit_base_10 = 10
};
-template <unsigned Digits, digit_base_type DigitBase = digit_base_10, class Allocator = void>
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4522) // multiple assignment operators specified
+#endif
+
+template <unsigned Digits, digit_base_type DigitBase = digit_base_10, class Allocator = void, class Exponent = int, Exponent MinExponent = 0, Exponent MaxExponent = 0>
class cpp_bin_float
{
public:
@@ -30,19 +35,27 @@
typedef typename rep_type::signed_types signed_types;
typedef typename rep_type::unsigned_types unsigned_types;
typedef boost::mpl::list<double, long double> float_types;
- typedef int exponent_type;
+ typedef Exponent exponent_type;
- static const int max_exponent = boost::integer_traits<int>::const_max - 2 * bit_count;
- static const int min_exponent = boost::integer_traits<int>::const_min + 2 * static_cast<int>(bit_count);
+ static const exponent_type max_exponent_limit = boost::integer_traits<exponent_type>::const_max - 2 * static_cast<exponent_type>(bit_count);
+ static const exponent_type min_exponent_limit = boost::integer_traits<exponent_type>::const_min + 2 * static_cast<exponent_type>(bit_count);
- static const int exponent_zero = max_exponent + 1;
- static const int exponent_infinity = max_exponent + 2;
- static const int exponent_nan = max_exponent + 3;
+ BOOST_STATIC_ASSERT_MSG(MinExponent >= min_exponent_limit, "Template parameter MinExponent is too negative for our internal logic to function correctly, sorry!");
+ BOOST_STATIC_ASSERT_MSG(MaxExponent <= max_exponent_limit, "Template parameter MaxExponent is too large for our internal logic to function correctly, sorry!");
+ BOOST_STATIC_ASSERT_MSG(MinExponent <= 0, "Template parameter MinExponent can not be positive!");
+ BOOST_STATIC_ASSERT_MSG(MaxExponent >= 0, "Template parameter MaxExponent can not be negative!");
+
+ static const exponent_type max_exponent = MaxExponent == 0 ? max_exponent_limit : MaxExponent;
+ static const exponent_type min_exponent = MinExponent == 0 ? min_exponent_limit : MinExponent;
+
+ static const exponent_type exponent_zero = max_exponent + 1;
+ static const exponent_type exponent_infinity = max_exponent + 2;
+ static const exponent_type exponent_nan = max_exponent + 3;
private:
rep_type m_data;
- boost::int32_t m_exponent;
+ exponent_type m_exponent;
bool m_sign;
public:
cpp_bin_float() : m_data(), m_exponent(exponent_nan), m_sign(false) {}
@@ -50,8 +63,29 @@
cpp_bin_float(const cpp_bin_float &o)
: m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {}
+ template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
+ cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE> &o, typename boost::enable_if_c<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = 0)
+ : m_exponent(o.exponent()), m_sign(o.sign())
+ {
+ typename cpp_bin_float<D, B, A, E, MinE, MaxE>::rep_type b(o.bits());
+ copy_and_round(*this, b);
+ }
+
+ template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
+ explicit cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE> &o, typename boost::disable_if_c<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = 0)
+ : m_exponent(o.exponent()), m_sign(o.sign())
+ {
+ typename cpp_bin_float<D, B, A, E, MinE, MaxE>::rep_type b(o.bits());
+ copy_and_round(*this, b);
+ }
+
template <class Float>
- cpp_bin_float(const Float& f, typename boost::enable_if_c<number_category<Float>::value == number_kind_floating_point>::type const* = 0)
+ cpp_bin_float(const Float& f,
+ typename boost::enable_if_c<
+ (number_category<Float>::value == number_kind_floating_point)
+ && (std::numeric_limits<Float>::digits <= bit_count)
+ && (std::numeric_limits<Float>::radix == 2)
+ >::type const* = 0)
: m_data(), m_exponent(0), m_sign(false)
{
this->assign_float(f);
@@ -65,8 +99,18 @@
return *this;
}
+ template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
+ typename boost::enable_if_c<bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count, cpp_bin_float&>::type operator=(const cpp_bin_float &o)
+ {
+ typename cpp_bin_float<D, B, A, E, MinE, MaxE>::rep_type b(o.bits());
+ copy_and_round(*this, b);
+ }
+
template <class Float>
- typename boost::enable_if_c<number_category<Float>::value == number_kind_floating_point, cpp_bin_float&>::type operator=(const Float& f)
+ typename boost::enable_if_c<
+ (number_category<Float>::value == number_kind_floating_point)
+ && (std::numeric_limits<Float>::digits <= bit_count)
+ && (std::numeric_limits<Float>::radix == 2), cpp_bin_float&>::type operator=(const Float& f)
{
return assign_float(f);
}
@@ -220,7 +264,7 @@
if(shift >= bit_count)
{
m_exponent = shift;
- m_data = static_cast<ui_type>(fi >> (shift + 1 - bit_count));
+ m_data = static_cast<limb_type>(fi >> (shift + 1 - bit_count));
}
else
{
@@ -280,8 +324,8 @@
rep_type& bits() { return m_data; }
const rep_type& bits()const { return m_data; }
- boost::int32_t& exponent() { return m_exponent; }
- const boost::int32_t& exponent()const { return m_exponent; }
+ exponent_type& exponent() { return m_exponent; }
+ const exponent_type& exponent()const { return m_exponent; }
bool& sign() { return m_sign; }
const bool& sign()const { return m_sign; }
void check_invariants()
@@ -301,11 +345,15 @@
}
};
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Int>
-inline void copy_and_round(cpp_bin_float<Digits, DigitBase, Allocator> &res, Int &arg)
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Int>
+inline void copy_and_round(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, Int &arg)
{
// Precondition: exponent of res must have been set before this function is called
- // as we may need to adjust it based on how many cpp_bin_float<Digits, DigitBase, Allocator>::bit_count in arg are set.
+ // as we may need to adjust it based on how many cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in arg are set.
using default_ops::eval_msb;
using default_ops::eval_lsb;
using default_ops::eval_left_shift;
@@ -317,37 +365,37 @@
// cancellation may have resulted in arg being all zeros:
if(eval_get_sign(arg) == 0)
{
- res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero;
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
res.sign() = false;
res.bits() = static_cast<limb_type>(0u);
return;
}
unsigned msb = eval_msb(arg);
- if(cpp_bin_float<Digits, DigitBase, Allocator>::bit_count > msb + 1)
+ if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count > msb + 1)
{
// Must have had cancellation in subtraction, shift left and copy:
- eval_left_shift(arg, cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - msb - 1);
- res.exponent() -= cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - msb - 1;
+ eval_left_shift(arg, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - msb - 1);
+ res.exponent() -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - msb - 1;
}
- else if(cpp_bin_float<Digits, DigitBase, Allocator>::bit_count < msb + 1)
+ else if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < msb + 1)
{
- // We have more cpp_bin_float<Digits, DigitBase, Allocator>::bit_count than we need, so round as required,
+ // We have more cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than we need, so round as required,
// first get the rounding bit:
- bool roundup = eval_bit_test(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count);
+ bool roundup = eval_bit_test(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count);
// Then check for a tie:
- if(roundup && (msb - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count == eval_lsb(arg)))
+ if(roundup && (msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count == eval_lsb(arg)))
{
// Ties round towards even:
- if(!eval_bit_test(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + 1))
+ if(!eval_bit_test(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1))
roundup = false;
}
- // Shift off the cpp_bin_float<Digits, DigitBase, Allocator>::bit_count we don't need:
- eval_right_shift(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + 1);
- res.exponent() += msb - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + 1;
+ // Shift off the cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count we don't need:
+ eval_right_shift(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1);
+ res.exponent() += msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
if(roundup)
{
eval_increment(arg);
- if(eval_bit_test(arg, cpp_bin_float<Digits, DigitBase, Allocator>::bit_count))
+ if(eval_bit_test(arg, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
{
// This happens very very rairly:
eval_right_shift(arg, 1u);
@@ -355,71 +403,71 @@
}
}
}
- BOOST_ASSERT((eval_msb(arg) == cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1));
+ BOOST_ASSERT((eval_msb(arg) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
res.bits() = arg;
- if(res.exponent() > cpp_bin_float<Digits, DigitBase, Allocator>::max_exponent)
+ if(res.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
{
// Overflow:
- res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity;
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
res.bits() = static_cast<limb_type>(0u);
}
- else if(res.exponent() < cpp_bin_float<Digits, DigitBase, Allocator>::min_exponent)
+ else if(res.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
{
// Underflow:
- res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero;
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
res.bits() = static_cast<limb_type>(0u);
res.sign() = false;
}
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void do_eval_add(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a, const cpp_bin_float<Digits, DigitBase, Allocator> &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void do_eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b)
{
using default_ops::eval_add;
using default_ops::eval_bit_test;
- typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type dt;
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
// Special cases first:
switch(a.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
res = b;
if(res.sign())
res.negate();
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
- if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan)
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
+ if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
res = b;
else
res = a;
return; // ault is still infinite.
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
res = a;
return; // ault is still a NaN.
}
switch(b.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
res = a;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
res = b;
if(res.sign())
res.negate();
return; // ault is infinite.
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
res = b;
return; // ault is a NaN.
}
- boost::int32_t e_diff = a.exponent() - b.exponent();
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type e_diff = a.exponent() - b.exponent();
bool s = a.sign();
if(e_diff >= 0)
{
dt = a.bits();
- if(e_diff < cpp_bin_float<Digits, DigitBase, Allocator>::bit_count)
+ if(e_diff < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
{
eval_left_shift(dt, e_diff);
res.exponent() = a.exponent() - e_diff;
@@ -431,7 +479,7 @@
else
{
dt= b.bits();
- if(-e_diff < cpp_bin_float<Digits, DigitBase, Allocator>::bit_count)
+ if(-e_diff < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
{
eval_left_shift(dt, -e_diff);
res.exponent() = b.exponent() + e_diff;
@@ -447,20 +495,20 @@
res.negate();
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void do_eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a, const cpp_bin_float<Digits, DigitBase, Allocator> &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void do_eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b)
{
using default_ops::eval_subtract;
using default_ops::eval_bit_test;
- typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type dt;
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
// Special cases first:
switch(a.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan)
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
else
{
res = b;
@@ -468,37 +516,37 @@
res.negate();
}
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
- if((b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan) || (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity))
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
+ if((b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan) || (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity))
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
else
res = a;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
res = a;
return; // result is still a NaN.
}
switch(b.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
res = a;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
- res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan;
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan;
res.sign() = false;
res.bits() = static_cast<limb_type>(0u);
return; // result is a NaN.
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
res = b;
return; // result is still a NaN.
}
- boost::int32_t e_diff = a.exponent() - b.exponent();
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type e_diff = a.exponent() - b.exponent();
bool s = a.sign();
if((e_diff > 0) || ((e_diff == 0) && a.bits().compare(b.bits()) >= 0))
{
dt = a.bits();
- if(e_diff < cpp_bin_float<Digits, DigitBase, Allocator>::bit_count)
+ if(e_diff < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
{
eval_left_shift(dt, e_diff);
res.exponent() = a.exponent() - e_diff;
@@ -510,7 +558,7 @@
else
{
dt = b.bits();
- if(-e_diff < cpp_bin_float<Digits, DigitBase, Allocator>::bit_count)
+ if(-e_diff < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
{
eval_left_shift(dt, -e_diff);
res.exponent() = b.exponent() + e_diff;
@@ -527,8 +575,8 @@
res.check_invariants();
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a, const cpp_bin_float<Digits, DigitBase, Allocator> &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b)
{
if(a.sign() == b.sign())
do_eval_add(res, a, b);
@@ -536,14 +584,14 @@
do_eval_subtract(res, a, b);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a)
{
return eval_add(res, res, a);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a, const cpp_bin_float<Digits, DigitBase, Allocator> &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b)
{
if(a.sign() != b.sign())
do_eval_add(res, a, b);
@@ -551,14 +599,14 @@
do_eval_subtract(res, a, b);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a)
{
return eval_subtract(res, res, a);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a, const cpp_bin_float<Digits, DigitBase, Allocator> &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b)
{
using default_ops::eval_bit_test;
using default_ops::eval_multiply;
@@ -566,19 +614,19 @@
// Special cases first:
switch(a.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan)
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
res = b;
else
res = a;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
switch(b.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
break;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
res = b;
break;
default:
@@ -586,21 +634,21 @@
break;
}
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
res = a;
return;
}
- if(b.exponent() > cpp_bin_float<Digits, DigitBase, Allocator>::max_exponent)
+ if(b.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
{
res = b;
return;
}
if((a.exponent() > 0) && (b.exponent() > 0))
{
- if(cpp_bin_float<Digits, DigitBase, Allocator>::max_exponent + 2 - a.exponent() < b.exponent())
+ if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + 2 - a.exponent() < b.exponent())
{
// We will certainly overflow:
- res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity;
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
res.sign() = a.sign() != b.sign();
res.bits() = static_cast<limb_type>(0u);
return;
@@ -608,32 +656,32 @@
}
if((a.exponent() < 0) && (b.exponent() < 0))
{
- if(cpp_bin_float<Digits, DigitBase, Allocator>::min_exponent - 2 - a.exponent() > b.exponent())
+ if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - 2 - a.exponent() > b.exponent())
{
// We will certainly underflow:
- res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero;
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
res.sign() = false;
res.bits() = static_cast<limb_type>(0u);
return;
}
}
- typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type dt;
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
eval_multiply(dt, a.bits(), b.bits());
- res.exponent() = a.exponent() + b.exponent() - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + 1;
+ res.exponent() = a.exponent() + b.exponent() - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
copy_and_round(res, dt);
res.check_invariants();
res.sign() = a.sign() != b.sign();
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a)
{
eval_multiply(res, res, a);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class U>
-inline typename enable_if_c<is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a, const U &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
+inline typename enable_if_c<is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const U &b)
{
using default_ops::eval_bit_test;
using default_ops::eval_multiply;
@@ -641,22 +689,22 @@
// Special cases first:
switch(a.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
res = a;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
if(b == 0)
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
else
res = a;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
res = a;
return;
}
- typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type dt;
- typedef typename boost::multiprecision::detail::canonical<U, typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type>::type canon_ui_type;
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
+ typedef typename boost::multiprecision::detail::canonical<U, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::type canon_ui_type;
eval_multiply(dt, a.bits(), static_cast<canon_ui_type>(b));
res.exponent() = a.exponent();
copy_and_round(res, dt);
@@ -664,14 +712,14 @@
res.sign() = a.sign();
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class U>
-inline typename enable_if_c<is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator> &res, const U &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
+inline typename enable_if_c<is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const U &b)
{
eval_multiply(res, res, b);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class S>
-inline typename enable_if_c<is_signed<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &a, const S &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
+inline typename enable_if_c<is_signed<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, const S &b)
{
typedef typename make_unsigned<S>::type ui_type;
eval_multiply(res, a, static_cast<ui_type>(boost::multiprecision::detail::abs(b)));
@@ -679,14 +727,14 @@
res.negate();
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class S>
-inline typename enable_if_c<is_signed<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator> &res, const S &b)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
+inline typename enable_if_c<is_signed<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const S &b)
{
eval_multiply(res, res, b);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &u, const cpp_bin_float<Digits, DigitBase, Allocator> &v)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &v)
{
using default_ops::eval_subtract;
using default_ops::eval_qr;
@@ -699,46 +747,46 @@
//
switch(u.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
switch(v.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
return;
}
res = u;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
switch(v.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
return;
}
res = u;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
return;
}
switch(v.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
{
bool s = u.sign() != v.sign();
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::infinity().backend();
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
res.sign() = s;
return;
}
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
- res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero;
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
res.bits() = limb_type(0);
res.sign() = false;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
return;
}
@@ -751,7 +799,7 @@
//
// q + r/v = u/v
//
- // From this, assuming q has "cpp_bin_float<Digits, DigitBase, Allocator>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator>::bit_count, we only need to determine whether
+ // From this, assuming q has "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, we only need to determine whether
// r/v is less than, equal to, or greater than 0.5 to determine rounding -
// this we can do with a shift and comparison.
//
@@ -762,21 +810,21 @@
//
// Now get the quotient and remainder:
//
- typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type t(u.bits()), t2(v.bits()), q, r;
- eval_left_shift(t, cpp_bin_float<Digits, DigitBase, Allocator>::bit_count);
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), t2(v.bits()), q, r;
+ eval_left_shift(t, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count);
eval_qr(t, t2, q, r);
//
- // We now have either "cpp_bin_float<Digits, DigitBase, Allocator>::bit_count" or "cpp_bin_float<Digits, DigitBase, Allocator>::bit_count+1" significant cpp_bin_float<Digits, DigitBase, Allocator>::bit_count in q.
+ // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
//
static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
- if(eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator>::bit_count))
+ if(eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
{
//
- // OK we have cpp_bin_float<Digits, DigitBase, Allocator>::bit_count+1 cpp_bin_float<Digits, DigitBase, Allocator>::bit_count, so we already have rounding info,
+ // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, so we already have rounding info,
// we just need to changes things if the last bit is 1 and the
// remainder is non-zero (ie we do not have a tie).
//
- BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator>::bit_count));
+ BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
if((q.limbs()[0] & 1u) && eval_get_sign(r))
{
eval_increment(q);
@@ -785,14 +833,14 @@
else
{
//
- // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator>::bit_count in q.
+ // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
// Get rounding info, which we can get by comparing 2r with v.
// We want to call copy_and_round to handle rounding and general cleanup,
// so we'll left shift q and add some fake digits on the end to represent
// how we'll be rounding.
//
- BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1));
- static const unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count < limb_bits ? 2 : limb_bits;
+ BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
+ static const unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits;
eval_left_shift(q, lshift);
res.exponent() -= lshift;
eval_left_shift(r, 1u);
@@ -805,14 +853,14 @@
copy_and_round(res, q);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
eval_divide(res, res, arg);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class U>
-inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &u, const U &v)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
+inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const U &v)
{
using default_ops::eval_subtract;
using default_ops::eval_qr;
@@ -825,25 +873,25 @@
//
switch(u.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
if(v == 0)
{
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
return;
}
res = u;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
res = u;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
return;
}
if(v == 0)
{
bool s = u.sign();
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::infinity().backend();
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
res.sign() = s;
return;
}
@@ -857,7 +905,7 @@
//
// q + r/v = u/v
//
- // From this, assuming q has "cpp_bin_float<Digits, DigitBase, Allocator>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator>::bit_count, we only need to determine whether
+ // From this, assuming q has "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, we only need to determine whether
// r/v is less than, equal to, or greater than 0.5 to determine rounding -
// this we can do with a shift and comparison.
//
@@ -869,21 +917,21 @@
//
// Now get the quotient and remainder:
//
- typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type t(u.bits()), q, r;
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), q, r;
eval_left_shift(t, gb + 1);
- eval_qr(t, number<typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type>::canonical_value(v), q, r);
+ eval_qr(t, number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v), q, r);
//
- // We now have either "cpp_bin_float<Digits, DigitBase, Allocator>::bit_count" or "cpp_bin_float<Digits, DigitBase, Allocator>::bit_count+1" significant cpp_bin_float<Digits, DigitBase, Allocator>::bit_count in q.
+ // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
//
static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
- if(eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator>::bit_count))
+ if(eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
{
//
- // OK we have cpp_bin_float<Digits, DigitBase, Allocator>::bit_count+1 cpp_bin_float<Digits, DigitBase, Allocator>::bit_count, so we already have rounding info,
+ // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, so we already have rounding info,
// we just need to changes things if the last bit is 1 and the
// remainder is non-zero (ie we do not have a tie).
//
- BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator>::bit_count));
+ BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
if((q.limbs()[0] & 1u) && eval_get_sign(r))
{
eval_increment(q);
@@ -892,18 +940,18 @@
else
{
//
- // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator>::bit_count in q.
+ // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
// Get rounding info, which we can get by comparing 2r with v.
// We want to call copy_and_round to handle rounding and general cleanup,
- // so we'll left shift q and add some fake cpp_bin_float<Digits, DigitBase, Allocator>::bit_count on the end to represent
+ // so we'll left shift q and add some fake cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count on the end to represent
// how we'll be rounding.
//
- BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1));
- static const unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count < limb_bits ? 2 : limb_bits;
+ BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
+ static const unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits;
eval_left_shift(q, lshift);
res.exponent() -= lshift;
eval_left_shift(r, 1u);
- int c = r.compare(number<typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type>::canonical_value(v));
+ int c = r.compare(number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v));
if(c == 0)
q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
else if(c > 0)
@@ -912,14 +960,14 @@
copy_and_round(res, q);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class U>
-inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator> &res, const U &v)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
+inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const U &v)
{
eval_divide(res, res, v);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class S>
-inline typename enable_if_c<is_signed<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &u, const S &v)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
+inline typename enable_if_c<is_signed<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const S &v)
{
typedef typename make_unsigned<S>::type ui_type;
eval_divide(res, u, static_cast<ui_type>(boost::multiprecision::detail::abs(v)));
@@ -927,38 +975,39 @@
res.negate();
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator, class S>
-inline typename enable_if_c<is_signed<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator> &res, const S &v)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
+inline typename enable_if_c<is_signed<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const S &v)
{
eval_divide(res, res, v);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
*res = 0;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
*res = (std::numeric_limits<long long>::max)();
if(arg.sign())
*res = -*res;
return;
}
- typename cpp_bin_float<Digits, DigitBase, Allocator>::rep_type man(arg.bits());
- int shift = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1 - arg.exponent();
- if(shift > cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1)
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
+ typename mpl::if_c<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type shift
+ = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
+ if(shift > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
{
*res = 0;
return;
}
else if(shift < 0)
{
- // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator>::bit_count than a long long?
+ // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than a long long?
*res = (std::numeric_limits<long long>::max)();
if(arg.sign())
*res = -*res;
@@ -970,30 +1019,31 @@
*res = -*res;
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_convert_to(unsigned long long *res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_convert_to(unsigned long long *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
*res = 0;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
*res = (std::numeric_limits<unsigned long long>::max)();
return;
}
- typename cpp_bin_float<Digits, DigitBase, Allocator>::rep_type man(arg.bits());
- int shift = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1 - arg.exponent();
- if(shift > cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1)
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
+ typename mpl::if_c<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type shift
+ = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
+ if(shift > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
{
*res = 0;
return;
}
else if(shift < 0)
{
- // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator>::bit_count than a long long?
+ // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than a long long?
*res = (std::numeric_limits<long long>::max)();
return;
}
@@ -1001,39 +1051,39 @@
eval_convert_to(res, man);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_convert_to(long double *res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_convert_to(long double *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
*res = 0;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
*res = std::numeric_limits<long double>::quiet_NaN();
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
*res = (std::numeric_limits<long double>::infinity)();
if(arg.sign())
*res = -*res;
return;
}
- int e = arg.exponent();
- e -= cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1;
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type e = arg.exponent();
+ e -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1;
eval_convert_to(res, arg.bits());
*res = std::ldexp(*res, e);
if(arg.sign())
*res = -*res;
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg, int *e)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, Exponent *e)
{
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
*e = 0;
res = arg;
return;
@@ -1043,14 +1093,26 @@
res.exponent() = -1;
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg, int e)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
+inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, I *pe)
+{
+ Exponent e;
+ eval_frexp(res, arg, &e);
+ if((e > (std::numeric_limits<I>::max)()) || (e < (std::numeric_limits<I>::min)()))
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Exponent was outside of the range of the argument type to frexp."));
+ }
+ *pe = static_cast<I>(e);
+}
+
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, Exponent e)
{
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
res = arg;
return;
}
@@ -1058,102 +1120,126 @@
res.exponent() += e;
}
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
+inline typename enable_if_c<is_unsigned<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, I e)
+{
+ typedef typename make_signed<I>::type si_type;
+ if(e > static_cast<I>((std::numeric_limits<si_type>::max)()))
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
+ else
+ eval_ldexp(res, arg, static_cast<si_type>(e));
+}
+
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
+inline typename enable_if_c<is_signed<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg, I e)
+{
+ if((e > (std::numeric_limits<Exponent>::max)()) || (e < (std::numeric_limits<Exponent>::min)()))
+ {
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
+ if(e < 0)
+ res.negate();
+ }
+ else
+ eval_ldexp(res, arg, static_cast<Exponent>(e));
+}
+
/*
* Sign manipulation
*/
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
res = arg;
res.sign() = false;
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
res = arg;
res.sign() = false;
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline int eval_fpclassify(const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline int eval_fpclassify(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
return FP_ZERO;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
return FP_INFINITE;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
return FP_NAN;
}
return FP_NORMAL;
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_sqrt(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_sqrt(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
using default_ops::eval_integer_sqrt;
using default_ops::eval_bit_test;
using default_ops::eval_increment;
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
res = arg;
return;
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
return;
}
if(arg.sign())
{
- res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
return;
}
- typename cpp_bin_float<Digits, DigitBase, Allocator>::double_rep_type t(arg.bits()), r, s;
- eval_left_shift(t, arg.exponent() & 1 ? cpp_bin_float<Digits, DigitBase, Allocator>::bit_count : cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1);
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(arg.bits()), r, s;
+ eval_left_shift(t, arg.exponent() & 1 ? cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count : cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1);
eval_integer_sqrt(s, r, t);
- if(!eval_bit_test(s, cpp_bin_float<Digits, DigitBase, Allocator>::bit_count))
+ if(!eval_bit_test(s, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
{
- // We have exactly the right number of cpp_bin_float<Digits, DigitBase, Allocator>::bit_count in the result, round as required:
+ // We have exactly the right number of cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in the result, round as required:
if(s.compare(r) < 0)
{
eval_increment(s);
}
}
- int ae = arg.exponent();
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type ae = arg.exponent();
res.exponent() = ae / 2;
if((ae & 1) && (ae < 0))
--res.exponent();
copy_and_round(res, s);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_floor(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_floor(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
using default_ops::eval_increment;
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
res = arg;
return;
}
- int shift = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - arg.exponent() - 1;
- if((arg.exponent() > cpp_bin_float<Digits, DigitBase, Allocator>::max_exponent) || (shift <= 0))
+ typename mpl::if_c<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type shift =
+ (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
+ if((arg.exponent() > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
{
// Either arg is already an integer, or a special value:
res = arg;
return;
}
- if(shift >= cpp_bin_float<Digits, DigitBase, Allocator>::bit_count)
+ if(shift >= (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
{
- res = arg.sign() ? -1 : 0;
+ res = static_cast<signed_limb_type>(arg.sign() ? -1 : 0);
return;
}
bool fractional = (int)eval_lsb(arg.bits()) < shift;
@@ -1162,7 +1248,7 @@
if(fractional && res.sign())
{
eval_increment(res.bits());
- if(eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1 - shift)
+ if(eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift)
{
// Must have extended result by one bit in the increment:
--shift;
@@ -1172,28 +1258,28 @@
eval_left_shift(res.bits(), shift);
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-inline void eval_ceil(cpp_bin_float<Digits, DigitBase, Allocator> &res, const cpp_bin_float<Digits, DigitBase, Allocator> &arg)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+inline void eval_ceil(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
using default_ops::eval_increment;
switch(arg.exponent())
{
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_zero:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_nan:
- case cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
res = arg;
return;
}
- int shift = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - arg.exponent() - 1;
- if((arg.exponent() > cpp_bin_float<Digits, DigitBase, Allocator>::max_exponent) || (shift <= 0))
+ typename mpl::if_c<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type shift = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
+ if((arg.exponent() > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
{
// Either arg is already an integer, or a special value:
res = arg;
return;
}
- if(shift >= cpp_bin_float<Digits, DigitBase, Allocator>::bit_count)
+ if(shift >= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
{
- res = arg.sign() ? 0 : 1;
+ res = static_cast<signed_limb_type>(arg.sign() ? 0 : 1);
return;
}
bool fractional = (int)eval_lsb(arg.bits()) < shift;
@@ -1202,7 +1288,7 @@
if(fractional && !res.sign())
{
eval_increment(res.bits());
- if(eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1 - shift)
+ if(eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift)
{
// Must have extended result by one bit in the increment:
--shift;
@@ -1214,18 +1300,32 @@
} // namespace backends
+#ifdef BOOST_NO_SFINAE_EXPR
+
+namespace detail{
+
+template<unsigned D1, backends::digit_base_type B1, class A1, unsigned D2, backends::digit_base_type B2, class A2>
+struct is_explicitly_convertible<backends::cpp_bin_float<D1, B1, A1>, backends::cpp_bin_float<D2, B2, A2> > : public mpl::true_ {};
+
+}
+#endif
+
+
using backends::cpp_bin_float;
using backends::digit_base_2;
using backends::digit_base_10;
-template<unsigned Digits, backends::digit_base_type DigitBase, class Allocator>
-struct number_category<cpp_bin_float<Digits, DigitBase, Allocator> > : public boost::mpl::int_<boost::multiprecision::number_kind_floating_point>{};
-
-typedef number<backends::cpp_bin_float<113, digit_base_2>, et_off> bin_float128;
+template<unsigned Digits, backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator>
+struct number_category<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > : public boost::mpl::int_<boost::multiprecision::number_kind_floating_point>{};
typedef number<backends::cpp_bin_float<50>, et_off> cpp_bin_float_50;
typedef number<backends::cpp_bin_float<100>, et_off> cpp_bin_float_100;
+typedef number<backends::cpp_bin_float<24, backends::digit_base_2, void, boost::int16_t, -126, 127>, et_off> float32_t;
+typedef number<backends::cpp_bin_float<53, backends::digit_base_2, void, boost::int16_t, -1022, 1023>, et_off> float64_t;
+typedef number<backends::cpp_bin_float<64, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> float80_t;
+typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> float128_t;
+
}} // namespaces
#include <boost/multiprecision/cpp_bin_float/io.hpp>
@@ -1235,10 +1335,10 @@
//
// numeric_limits [partial] specializations for the types declared in this header:
//
-template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >
+template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >
{
- typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> number_type;
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> number_type;
public:
BOOST_STATIC_CONSTEXPR bool is_specialized = true;
static number_type (min)()
@@ -1249,7 +1349,7 @@
{
value.first = true;
value.second = 1u;
- value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>::min_exponent;
+ value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
}
return value.second;
}
@@ -1261,7 +1361,7 @@
{
value.first = true;
eval_complement(value.second.backend().bits(), value.second.backend().bits());
- value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>::max_exponent;
+ value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
}
return value.second;
}
@@ -1269,7 +1369,7 @@
{
return -(max)();
}
- BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>::bit_count;
+ BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count;
BOOST_STATIC_CONSTEXPR int digits10 = digits * 301 / 1000;
// Is this really correct???
BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
@@ -1303,10 +1403,10 @@
}
return value.second;
}
- BOOST_STATIC_CONSTEXPR long min_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>::min_exponent;
- BOOST_STATIC_CONSTEXPR long min_exponent10 = (min_exponent / 1000) * 301L;
- BOOST_STATIC_CONSTEXPR long max_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>::max_exponent;
- BOOST_STATIC_CONSTEXPR long max_exponent10 = (max_exponent / 1000) * 301L;
+ BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
+ BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent10 = (min_exponent / 1000) * 301L;
+ BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
+ BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent10 = (max_exponent / 1000) * 301L;
BOOST_STATIC_CONSTEXPR bool has_infinity = true;
BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
@@ -1320,7 +1420,7 @@
if(!value.first)
{
value.first = true;
- value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>::exponent_infinity;
+ value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
}
return value.second;
}
@@ -1344,67 +1444,67 @@
{
data_initializer()
{
- std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator> > >::epsilon();
- std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator> > >::round_error();
- (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator> > >::min)();
- (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator> > >::max)();
- std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator> > >::infinity();
- std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN();
+ std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::epsilon();
+ std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::round_error();
+ (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::min)();
+ (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::max)();
+ std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity();
+ std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN();
}
void do_nothing()const{}
};
static const data_initializer initializer;
};
-template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::initializer;
+template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::initializer;
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::digits;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::digits10;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::max_digits10;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::is_signed;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::is_integer;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::is_exact;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::radix;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::min_exponent;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::min_exponent10;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::max_exponent;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::max_exponent10;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::has_infinity;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::has_quiet_NaN;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::has_signaling_NaN;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::has_denorm;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::has_denorm_loss;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::is_iec559;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::is_bounded;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::is_modulo;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::traps;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::tinyness_before;
-template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator>, ExpressionTemplates> >::round_style;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits10;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_digits10;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_signed;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_integer;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_exact;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::radix;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent10;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent10;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_infinity;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_quiet_NaN;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_signaling_NaN;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm_loss;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_iec559;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_bounded;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_modulo;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::traps;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::tinyness_before;
+template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::round_style;
#endif
Modified: sandbox/multiprecision.cpp_bin_float/boost/multiprecision/cpp_bin_float/io.hpp
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/boost/multiprecision/cpp_bin_float/io.hpp Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/boost/multiprecision/cpp_bin_float/io.hpp 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -12,29 +12,34 @@
// Multiplies a by b and shifts the result so it fits inside max_bits bits,
// returns by how much the result was shifted.
//
-inline int restricted_multiply(cpp_int& result, const cpp_int& a, const cpp_int& b, int max_bits, boost::int64_t& error)
+template <class I>
+inline I restricted_multiply(cpp_int& result, const cpp_int& a, const cpp_int& b, I max_bits, boost::int64_t& error)
{
result = a * b;
- int gb = msb(result);
- int rshift = 0;
+ I gb = msb(result);
+ I rshift = 0;
if(gb > max_bits)
{
rshift = gb - max_bits;
- int lb = lsb(result);
+ I lb = lsb(result);
int roundup = 0;
// The error rate increases by the error of both a and b,
// this may be overly pessimistic in many case as we're assuming
// that a and b have the same level of uncertainty...
if(lb < rshift)
error = error ? error * 2 : 1;
- if(bit_test(result, rshift - 1))
+ if(rshift)
{
- if(lb == rshift - 1)
- roundup = 1;
- else
- roundup = 2;
+ BOOST_ASSERT(rshift < INT_MAX);
+ if(bit_test(result, static_cast<unsigned>(rshift - 1)))
+ {
+ if(lb == rshift - 1)
+ roundup = 1;
+ else
+ roundup = 2;
+ }
+ result >>= rshift;
}
- result >>= rshift;
if((roundup == 2) || ((roundup == 1) && (result.backend().limbs()[0] & 1)))
++result;
}
@@ -44,10 +49,11 @@
// Computes a^e shifted to the right so it fits in max_bits, returns how far
// to the right we are shifted.
//
-inline int restricted_pow(cpp_int& result, const cpp_int& a, int e, int max_bits, boost::int64_t& error)
+template <class I>
+inline I restricted_pow(cpp_int& result, const cpp_int& a, I e, I max_bits, boost::int64_t& error)
{
BOOST_ASSERT(&result != &a);
- int exp = 0;
+ I exp = 0;
if(e == 1)
{
result = a;
@@ -63,7 +69,7 @@
exp += restricted_multiply(result, result, a, max_bits, error);
return exp;
}
- int p = e / 2;
+ I p = e / 2;
exp = restricted_pow(result, a, p, max_bits, error);
exp *= 2;
exp += restricted_multiply(result, result, result, max_bits, error);
@@ -72,7 +78,7 @@
return exp;
}
-inline int get_round_mode(const cpp_int& what, int location, boost::int64_t error)
+inline int get_round_mode(const cpp_int& what, boost::int64_t location, boost::int64_t error)
{
//
// Can we round what at /location/, if the error in what is /error/ in
@@ -83,10 +89,12 @@
// 1: tie.
// 2: round up.
//
+ BOOST_ASSERT(location >= 0);
+ BOOST_ASSERT(location < INT_MAX);
boost::int64_t error_radius = error & 1 ? (1 + error) / 2 : error / 2;
if(error_radius && ((int)msb(error_radius) >= location))
return -1;
- if(bit_test(what, location))
+ if(bit_test(what, static_cast<unsigned>(location)))
{
if((int)lsb(what) == location)
return error ? -1 : 1; // Either a tie or can't round depending on whether we have any error
@@ -100,7 +108,7 @@
else if(error)
{
cpp_int t = what + error_radius;
- return bit_test(t, location) ? -1 : 0;
+ return bit_test(t, static_cast<unsigned>(location)) ? -1 : 0;
}
return 0;
}
@@ -155,13 +163,13 @@
namespace backends{
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-cpp_bin_float<Digits, DigitBase, Allocator>& cpp_bin_float<Digits, DigitBase, Allocator>::operator=(const char *s)
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::operator=(const char *s)
{
cpp_int n;
- int decimal_exp = 0;
- int digits_seen = 0;
- static const int max_digits_seen = 4 + (cpp_bin_float<Digits, DigitBase, Allocator>::bit_count * 301L) / 1000;
+ boost::intmax_t decimal_exp = 0;
+ boost::intmax_t digits_seen = 0;
+ static const boost::intmax_t max_digits_seen = 4 + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count * 301L) / 1000;
bool ss = false;
//
// Extract the sign:
@@ -178,11 +186,11 @@
//
if((std::strcmp(s, "nan") == 0) || (std::strcmp(s, "NaN") == 0) || (std::strcmp(s, "NAN") == 0))
{
- return *this = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::quiet_NaN().backend();
+ return *this = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
}
if((std::strcmp(s, "inf") == 0) || (std::strcmp(s, "Inf") == 0) || (std::strcmp(s, "INF") == 0) || (std::strcmp(s, "infinity") == 0) || (std::strcmp(s, "Infinity") == 0) || (std::strcmp(s, "INFINITY") == 0))
{
- *this = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::infinity().backend();
+ *this = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
if(ss)
negate();
return *this;
@@ -226,8 +234,8 @@
if(*s && ((*s == 'e') || (*s == 'E')))
{
++s;
- int e = 0;
- int es = false;
+ boost::intmax_t e = 0;
+ bool es = false;
if(*s && (*s == '-'))
{
es = true;
@@ -262,22 +270,22 @@
static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
//
// Set our working precision - this is heuristic based, we want
- // a value as small as possible > cpp_bin_float<Digits, DigitBase, Allocator>::bit_count to avoid large computations
+ // a value as small as possible > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count to avoid large computations
// and excessive memory usage, but we also want to avoid having to
// up the computation and start again at a higher precision.
- // So we round cpp_bin_float<Digits, DigitBase, Allocator>::bit_count up to the nearest whole number of limbs, and add
+ // So we round cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count up to the nearest whole number of limbs, and add
// one limb for good measure. This works very well for small exponents,
// but for larger exponents we may may need to restart, we could add some
// extra precision right from the start for larger exponents, but this
// seems to be slightly slower in the *average* case:
//
#ifdef BOOST_MP_STRESS_IO
- int max_bits = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + 32;
+ boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32;
#else
- int max_bits = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + (cpp_bin_float<Digits, DigitBase, Allocator>::bit_count % limb_bits ? limb_bits - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count % limb_bits : 0) + limb_bits;
+ boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits ? limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits : 0) + limb_bits;
#endif
boost::int64_t error = 0;
- int calc_exp = 0;
+ boost::intmax_t calc_exp = 0;
if(decimal_exp >= 0)
{
@@ -292,10 +300,10 @@
}
else
t = n;
- exponent() = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1;
- exponent() += decimal_exp;
- exponent() += calc_exp;
- int rshift = msb(t) - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + 1;
+ exponent() = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1;
+ exponent() += static_cast<exponent_type>(decimal_exp);
+ exponent() += static_cast<exponent_type>(calc_exp);
+ int rshift = msb(t) - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
if(rshift > 0)
{
exponent() += rshift;
@@ -336,8 +344,8 @@
{
cpp_int d;
calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(d, cpp_int(5), -decimal_exp, max_bits, error);
- int shift = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - msb(n) + msb(d);
- exponent() = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1 + decimal_exp - calc_exp;
+ int shift = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - msb(n) + msb(d);
+ exponent() = static_cast<exponent_type>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 + decimal_exp - calc_exp);
if(shift > 0)
{
n <<= shift;
@@ -346,25 +354,25 @@
cpp_int q, r;
divide_qr(n, d, q, r);
int gb = msb(q);
- BOOST_ASSERT((gb >= cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1));
+ BOOST_ASSERT((gb >= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
//
// Check for rounding conditions we have to
// handle ourselves:
//
int roundup = 0;
- if(gb == cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1)
+ if(gb == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
{
// Exactly the right number of bits, use the remainder to round:
roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(r, d, error, q);
}
- else if(bit_test(q, gb - (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count) && ((int)lsb(q) == (gb - (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count)))
+ else if(bit_test(q, gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) && ((int)lsb(q) == (gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)))
{
// Too many bits in q and the bits in q indicate a tie, but we can break that using r,
// note that the radius of error in r is error/2 * q:
- int shift = gb - (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + 1;
+ int shift = gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
q >>= shift;
exponent() += shift;
- BOOST_ASSERT((msb(q) >= cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - 1));
+ BOOST_ASSERT((msb(q) >= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
if(error && (r < (error / 2) * q))
roundup = -1;
else if(error && (r + (error / 2) * q >= d))
@@ -405,23 +413,23 @@
return *this;
}
-template <unsigned Digits, digit_base_type DigitBase, class Allocator>
-std::string cpp_bin_float<Digits, DigitBase, Allocator>::str(std::streamsize dig, std::ios_base::fmtflags f) const
+template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
+std::string cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::str(std::streamsize dig, std::ios_base::fmtflags f) const
{
if(dig == 0)
- dig = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator> > >::max_digits10;
+ dig = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::max_digits10;
bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
bool fixed = !scientific && (f & std::ios_base::fixed);
std::string s;
- if(exponent() <= cpp_bin_float<Digits, DigitBase, Allocator>::max_exponent)
+ if(exponent() <= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
{
// How far to left-shift in order to demormalise the mantissa:
- int shift = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - exponent() - 1;
- int digits_wanted = static_cast<int>(dig);
- int base10_exp = exponent() >= 0 ? static_cast<int>(std::floor(0.30103 * exponent())) : static_cast<int>(std::ceil(0.30103 * exponent()));
+ boost::intmax_t shift = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1;
+ boost::intmax_t digits_wanted = static_cast<int>(dig);
+ boost::intmax_t base10_exp = exponent() >= 0 ? static_cast<boost::intmax_t>(std::floor(0.30103 * exponent())) : static_cast<boost::intmax_t>(std::ceil(0.30103 * exponent()));
//
// For fixed formatting we want /dig/ digits after the decimal point,
// so if the exponent is zero, allowing for the one digit before the
@@ -444,7 +452,7 @@
// power10 is the base10 exponent we need to multiply/divide by in order
// to convert our denormalised number to an integer with the right number of digits:
//
- int power10 = digits_wanted - base10_exp - 1;
+ boost::intmax_t power10 = digits_wanted - base10_exp - 1;
//
// If we calculate 5^power10 rather than 10^power10 we need to move
// 2^power10 into /shift/
@@ -455,24 +463,24 @@
static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
//
// Set our working precision - this is heuristic based, we want
- // a value as small as possible > cpp_bin_float<Digits, DigitBase, Allocator>::bit_count to avoid large computations
+ // a value as small as possible > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count to avoid large computations
// and excessive memory usage, but we also want to avoid having to
// up the computation and start again at a higher precision.
- // So we round cpp_bin_float<Digits, DigitBase, Allocator>::bit_count up to the nearest whole number of limbs, and add
+ // So we round cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count up to the nearest whole number of limbs, and add
// one limb for good measure. This works very well for small exponents,
// but for larger exponents we add a few extra limbs to max_bits:
//
#ifdef BOOST_MP_STRESS_IO
- int max_bits = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + 32;
+ boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32;
#else
- int max_bits = cpp_bin_float<Digits, DigitBase, Allocator>::bit_count + (cpp_bin_float<Digits, DigitBase, Allocator>::bit_count % limb_bits ? limb_bits - cpp_bin_float<Digits, DigitBase, Allocator>::bit_count % limb_bits : 0) + limb_bits;
+ boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits ? limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits : 0) + limb_bits;
if(power10)
max_bits += (msb(std::abs(power10)) / 8) * limb_bits;
#endif
do
{
boost::int64_t error = 0;
- int calc_exp = 0;
+ boost::intmax_t calc_exp = 0;
//
// Our integer result is: bits() * 2^-shift * 5^power10
//
@@ -483,9 +491,10 @@
{
// We go straight to the answer with all integer arithmetic,
// the result is always exact and never needs rounding:
+ BOOST_ASSERT(power10 <= (boost::intmax_t)INT_MAX);
i <<= -shift;
if(power10)
- i *= pow(cpp_int(5), power10);
+ i *= pow(cpp_int(5), static_cast<unsigned>(power10));
}
else if(power10 < 0)
{
@@ -504,7 +513,7 @@
#else
max_bits *= 2;
#endif
- shift = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - exponent() - 1 - power10;
+ shift = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10;
continue;
}
}
@@ -532,7 +541,7 @@
#else
max_bits *= 2;
#endif
- shift = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - exponent() - 1 - power10;
+ shift = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10;
continue;
}
if(shift)
@@ -545,7 +554,7 @@
#else
max_bits *= 2;
#endif
- shift = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - exponent() - 1 - power10;
+ shift = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10;
continue;
}
i >>= shift;
@@ -557,7 +566,8 @@
// so 5^-power10 can never be that large or we'd simply
// get zero as a result, and that case is already handled above:
cpp_int r;
- cpp_int d = pow(cpp_int(5), -power10);
+ BOOST_ASSERT(-power10 < INT_MAX);
+ cpp_int d = pow(cpp_int(5), static_cast<unsigned>(-power10));
d <<= shift;
divide_qr(i, d, i, r);
r <<= 1;
@@ -578,7 +588,7 @@
if(fixed)
digits_wanted = digits_got; // strange but true.
power10 = digits_wanted - base10_exp - 1;
- shift = (int)cpp_bin_float<Digits, DigitBase, Allocator>::bit_count - exponent() - 1 - power10;
+ shift = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10;
if(fixed)
break;
roundup = 0;
Modified: sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/ref.html
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/ref.html Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/ref.html 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -6,12 +6,12 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="Chapter 1. Boost.Multiprecision">
<link rel="up" href="../index.html" title="Chapter 1. Boost.Multiprecision">
-<link rel="prev" href="tut/limits/limits32.html" title="Numeric limits for 32-bit platform">
+<link rel="prev" href="tut/input_output.html" title="Input Output">
<link rel="next" href="ref/number.html" title="number">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="spirit-nav">
-<a accesskey="p" href="tut/limits/limits32.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="ref/number.html"><img src="../images/next.png" alt="Next"></a>
+<a accesskey="p" href="tut/input_output.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="ref/number.html"><img src="../images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -41,7 +41,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
-<a accesskey="p" href="tut/limits/limits32.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="ref/number.html"><img src="../images/next.png" alt="Next"></a>
+<a accesskey="p" href="tut/input_output.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="ref/number.html"><img src="../images/next.png" alt="Next"></a>
</div>
</body>
</html>
Modified: sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut.html
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut.html Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut.html 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -124,6 +124,7 @@
<dt><span class="section"><a href="tut/limits/limits32.html">Numeric limits
for 32-bit platform</a></span></dt>
</dl></dd>
+<dt><span class="section">Input Output</span></dt>
</dl></div>
<p>
In order to use this library you need to make two choices:
Modified: sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut/limits/limits32.html
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut/limits/limits32.html Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut/limits/limits32.html 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -7,11 +7,11 @@
<link rel="home" href="../../../index.html" title="Chapter 1. Boost.Multiprecision">
<link rel="up" href="../limits.html" title="Numeric Limits">
<link rel="prev" href="version_32.html" title="32-bit version information used for tables below.">
-<link rel="next" href="../../ref.html" title="Reference">
+<link rel="next" href="../input_output.html" title="Input Output">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="spirit-nav">
-<a accesskey="p" href="version_32.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../limits.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../../ref.html"><img src="../../../images/next.png" alt="Next"></a>
+<a accesskey="p" href="version_32.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../limits.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../input_output.html"><img src="../../../images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
@@ -2020,7 +2020,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
-<a accesskey="p" href="version_32.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../limits.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../../ref.html"><img src="../../../images/next.png" alt="Next"></a>
+<a accesskey="p" href="version_32.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../limits.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../input_output.html"><img src="../../../images/next.png" alt="Next"></a>
</div>
</body>
</html>
Modified: sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut/misc/visualizers.html
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut/misc/visualizers.html Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/boost_multiprecision/tut/misc/visualizers.html 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -24,7 +24,7 @@
partial solution in the shape of "visualizers" which provide
improved views of complex data structures, these visualizers need to be
added to the <code class="computeroutput"><span class="special">[</span><span class="identifier">Visualizer</span><span class="special">]</span></code> section of <code class="computeroutput"><span class="identifier">autoexp</span><span class="special">.</span><span class="identifier">dat</span></code>
- located in the <code class="computeroutput"><span class="identifier">Common7</span><span class="special">\</span><span class="identifier">Packages</span><span class="special">\</span><span class="identifier">Debugger</span></code>
+ located in the <code class="computeroutput"><span class="identifier">Common7</span><span class="special">/</span><span class="identifier">Packages</span><span class="special">/</span><span class="identifier">Debugger</span></code>
directory of your Visual Studio installation. The actual visualizer code
is in the sandbox here
- just cut and paste the code into your <code class="computeroutput"><span class="identifier">autoexp</span><span class="special">.</span><span class="identifier">dat</span></code>
Modified: sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/index.html
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/index.html Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/html/index.html 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -106,6 +106,7 @@
<dt><span class="section"><a href="boost_multiprecision/tut/limits/limits32.html">Numeric limits
for 32-bit platform</a></span></dt>
</dl></dd>
+<dt><span class="section">Input Output</span></dt>
</dl></dd>
<dt><span class="section">Reference</span></dt>
<dd><dl>
@@ -148,7 +149,7 @@
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
-<td align="left"><p><small>Last revised: October 15, 2013 at 16:13:05 GMT</small></p></td>
+<td align="left"><p><small>Last revised: October 16, 2013 at 11:16:57 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
Modified: sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/multiprecision.qbk
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/multiprecision.qbk Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/libs/multiprecision/doc/multiprecision.qbk 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -35,7 +35,7 @@
[import ../example/safe_prime.cpp]
[import ../example/mixed_integer_arithmetic.cpp]
[import ../example/logged_adaptor.cpp]
-[/[import ../example/numeric_limits_snips.cpp]]
+[import ../example/numeric_limits_snips.cpp]
[template mpfr[] [@http://www.mpfr.org MPFR]]
[template mpfi[] [@http://perso.ens-lyon.fr/nathalie.revol/software.html MPFI]]
@@ -2222,7 +2222,7 @@
The extra two (or 3) least significant digits are 'noisy' and may be junk,
but if you want to 'round-trip' - printing a value out and reading it back in -
-you must use then with `os.precision(std::numeric_limits<T>::max_digits10)`.
+you must use `os.precision(std::numeric_limits<T>::max_digits10)`.
For at least one popular compiler, you must also use `std::scientific` format.
[endsect] [/section:digits digits]
@@ -2276,8 +2276,6 @@
[@http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF Kahan formula for floating-point type T].
See above.]
-See also `max_digits10_proxy`.
-
[max_digits10_1] [/ example for using max_digits10]
[endsect] [/section:max_digits10 max_digits10]
Modified: sandbox/multiprecision.cpp_bin_float/libs/multiprecision/test/test_arithmetic_cpp_bin_float_1.cpp
==============================================================================
--- sandbox/multiprecision.cpp_bin_float/libs/multiprecision/test/test_arithmetic_cpp_bin_float_1.cpp Wed Oct 16 11:43:02 2013 (r86334)
+++ sandbox/multiprecision.cpp_bin_float/libs/multiprecision/test/test_arithmetic_cpp_bin_float_1.cpp 2013-10-16 13:49:10 EDT (Wed, 16 Oct 2013) (r86335)
@@ -19,7 +19,9 @@
int main()
{
- test<boost::multiprecision::cpp_bin_float_50>();
+ //test<boost::multiprecision::cpp_bin_float_50>();
+ //test<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<21> > >();
+ test<boost::multiprecision::float80_t>();
return boost::report_errors();
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk