1 ///////////////////////////////////////////////////////////////
2 //  Copyright 2013 John Maddock. Distributed under the Boost
3 //  Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
5 
6 #ifndef BOOST_MATH_CPP_BIN_FLOAT_HPP
7 #define BOOST_MATH_CPP_BIN_FLOAT_HPP
8 
9 #include <boost/multiprecision/cpp_int.hpp>
10 #include <boost/multiprecision/integer.hpp>
11 #include <boost/math/special_functions/trunc.hpp>
12 #include <boost/multiprecision/detail/float_string_cvt.hpp>
13 
14 //
15 // Some includes we need from Boost.Math, since we rely on that library to provide these functions:
16 //
17 #include <boost/math/special_functions/asinh.hpp>
18 #include <boost/math/special_functions/acosh.hpp>
19 #include <boost/math/special_functions/atanh.hpp>
20 #include <boost/math/special_functions/cbrt.hpp>
21 #include <boost/math/special_functions/expm1.hpp>
22 #include <boost/math/special_functions/gamma.hpp>
23 
24 namespace boost{ namespace multiprecision{ namespace backends{
25 
26 enum digit_base_type
27 {
28    digit_base_2 = 2,
29    digit_base_10 = 10
30 };
31 
32 #ifdef BOOST_MSVC
33 #pragma warning(push)
34 #pragma warning(disable:4522 6326)  // multiple assignment operators specified, comparison of two constants
35 #endif
36 
37 namespace detail{
38 
39 template <class U>
is_negative(U)40 inline typename enable_if_c<is_unsigned<U>::value, bool>::type is_negative(U) { return false; }
41 template <class S>
is_negative(S s)42 inline typename disable_if_c<is_unsigned<S>::value, bool>::type is_negative(S s) { return s < 0; }
43 
44 }
45 
46 template <unsigned Digits, digit_base_type DigitBase = digit_base_10, class Allocator = void, class Exponent = int, Exponent MinExponent = 0, Exponent MaxExponent = 0>
47 class cpp_bin_float
48 {
49 public:
50    static const unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + (((Digits * 1000uL) % 301) ? 2u : 1u);
51    typedef cpp_int_backend<is_void<Allocator>::value ? bit_count : 0, bit_count, is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> rep_type;
52    typedef cpp_int_backend<is_void<Allocator>::value ? 2 * bit_count : 0, 2 * bit_count, is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> double_rep_type;
53 
54    typedef typename rep_type::signed_types                        signed_types;
55    typedef typename rep_type::unsigned_types                      unsigned_types;
56    typedef boost::mpl::list<float, double, long double>           float_types;
57    typedef Exponent                                               exponent_type;
58 
59    static const exponent_type max_exponent_limit = boost::integer_traits<exponent_type>::const_max - 2 * static_cast<exponent_type>(bit_count);
60    static const exponent_type min_exponent_limit = boost::integer_traits<exponent_type>::const_min + 2 * static_cast<exponent_type>(bit_count);
61 
62    BOOST_STATIC_ASSERT_MSG(MinExponent >= min_exponent_limit, "Template parameter MinExponent is too negative for our internal logic to function correctly, sorry!");
63    BOOST_STATIC_ASSERT_MSG(MaxExponent <= max_exponent_limit, "Template parameter MaxExponent is too large for our internal logic to function correctly, sorry!");
64    BOOST_STATIC_ASSERT_MSG(MinExponent <= 0, "Template parameter MinExponent can not be positive!");
65    BOOST_STATIC_ASSERT_MSG(MaxExponent >= 0, "Template parameter MaxExponent can not be negative!");
66 
67    static const exponent_type max_exponent = MaxExponent == 0 ? max_exponent_limit : MaxExponent;
68    static const exponent_type min_exponent = MinExponent == 0 ? min_exponent_limit : MinExponent;
69 
70    static const exponent_type exponent_zero = max_exponent + 1;
71    static const exponent_type exponent_infinity = max_exponent + 2;
72    static const exponent_type exponent_nan = max_exponent + 3;
73 
74 private:
75 
76    rep_type m_data;
77    exponent_type m_exponent;
78    bool m_sign;
79 public:
BOOST_MP_NOEXCEPT_IF(noexcept (rep_type ()))80    cpp_bin_float() BOOST_MP_NOEXCEPT_IF(noexcept(rep_type())) : m_data(), m_exponent(exponent_zero), m_sign(false) {}
81 
BOOST_MP_NOEXCEPT_IF(noexcept (rep_type (std::declval<const rep_type &> ())))82    cpp_bin_float(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(rep_type(std::declval<const rep_type&>())))
83       : m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {}
84 
85    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)86    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)
87    {
88       *this = o;
89    }
90    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::disable_if_c<(bit_count>=cpp_bin_float<D,B,A,E,MinE,MaxE>::bit_count)>::type const * =0)91    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)
92       : m_exponent(o.exponent()), m_sign(o.sign())
93    {
94       *this = o;
95    }
96    template <class Float>
cpp_bin_float(const Float & f,typename boost::enable_if_c<(number_category<Float>::value==number_kind_floating_point)&& (std::numeric_limits<Float>::digits<=(int)bit_count)&& (std::numeric_limits<Float>::radix==2)>::type const * =0)97    cpp_bin_float(const Float& f,
98       typename boost::enable_if_c<
99          (number_category<Float>::value == number_kind_floating_point)
100          && (std::numeric_limits<Float>::digits <= (int)bit_count)
101          && (std::numeric_limits<Float>::radix == 2)
102       >::type const* = 0)
103       : m_data(), m_exponent(0), m_sign(false)
104    {
105       this->assign_float(f);
106    }
107 
108    template <class Float>
cpp_bin_float(const Float & f,typename boost::enable_if_c<(number_category<Float>::value==number_kind_floating_point)&& (std::numeric_limits<Float>::digits> (int)bit_count)&& (std::numeric_limits<Float>::radix==2)>::type const * =0)109    explicit cpp_bin_float(const Float& f,
110       typename boost::enable_if_c<
111       (number_category<Float>::value == number_kind_floating_point)
112       && (std::numeric_limits<Float>::digits > (int)bit_count)
113       && (std::numeric_limits<Float>::radix == 2)
114       >::type const* = 0)
115       : m_data(), m_exponent(0), m_sign(false)
116    {
117       this->assign_float(f);
118    }
119 
operator =(const cpp_bin_float & o)120    cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
121    {
122       m_data = o.m_data;
123       m_exponent = o.m_exponent;
124       m_sign = o.m_sign;
125       return *this;
126    }
127 
128    template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
operator =(const cpp_bin_float<D,B,A,E,MinE,MaxE> & f)129    cpp_bin_float& operator=(const cpp_bin_float<D, B, A, E, MinE, MaxE> &f)
130    {
131       switch(eval_fpclassify(f))
132       {
133       case FP_ZERO:
134          m_data = limb_type(0);
135          m_sign = f.sign();
136          m_exponent = exponent_zero;
137          break;
138       case FP_NAN:
139          m_data = limb_type(0);
140          m_sign = false;
141          m_exponent = exponent_nan;
142          break;;
143       case FP_INFINITE:
144          m_data = limb_type(0);
145          m_sign = f.sign();
146          m_exponent = exponent_infinity;
147          break;
148       default:
149          typename cpp_bin_float<D, B, A, E, MinE, MaxE>::rep_type b(f.bits());
150          this->exponent() = f.exponent() + (int)bit_count - (int)cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count;
151          this->sign() = f.sign();
152          copy_and_round(*this, b);
153       }
154       return *this;
155    }
156 
157    template <class Float>
158    typename boost::enable_if_c<
159       (number_category<Float>::value == number_kind_floating_point)
160       //&& (std::numeric_limits<Float>::digits <= (int)bit_count)
operator =(const Float & f)161       && (std::numeric_limits<Float>::radix == 2), cpp_bin_float&>::type operator=(const Float& f)
162    {
163       return assign_float(f);
164    }
165 
166    template <class Float>
assign_float(Float f)167    typename boost::enable_if_c<is_floating_point<Float>::value, cpp_bin_float&>::type assign_float(Float f)
168    {
169       BOOST_MATH_STD_USING
170       using default_ops::eval_add;
171       typedef typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type bf_int_type;
172 
173       switch((boost::math::fpclassify)(f))
174       {
175       case FP_ZERO:
176          m_data = limb_type(0);
177          m_sign = ((boost::math::signbit)(f) > 0);
178          m_exponent = exponent_zero;
179          return *this;
180       case FP_NAN:
181          m_data = limb_type(0);
182          m_sign = false;
183          m_exponent = exponent_nan;
184          return *this;
185       case FP_INFINITE:
186          m_data = limb_type(0);
187          m_sign = (f < 0);
188          m_exponent = exponent_infinity;
189          return *this;
190       }
191       if(f < 0)
192       {
193          *this = -f;
194          this->negate();
195          return *this;
196       }
197 
198       typedef typename mpl::front<unsigned_types>::type ui_type;
199       m_data = static_cast<ui_type>(0u);
200       m_sign = false;
201       m_exponent = 0;
202 
203       static const int bits = sizeof(int) * CHAR_BIT - 1;
204       int e;
205       f = frexp(f, &e);
206       while(f)
207       {
208          f = ldexp(f, bits);
209          e -= bits;
210 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
211          int ipart = itrunc(f);
212 #else
213          int ipart = static_cast<int>(f);
214 #endif
215          f -= ipart;
216          m_exponent += bits;
217          cpp_bin_float t;
218          t = static_cast<bf_int_type>(ipart);
219          eval_add(*this, t);
220       }
221       m_exponent += static_cast<Exponent>(e);
222       return *this;
223    }
224 
225    template <class Float>
226    typename boost::enable_if_c<
227       (number_category<Float>::value == number_kind_floating_point)
228          && !boost::is_floating_point<Float>::value
229          /*&& (std::numeric_limits<number<Float> >::radix == 2)*/,
assign_float(Float f)230       cpp_bin_float&>::type assign_float(Float f)
231    {
232       BOOST_MATH_STD_USING
233       using default_ops::eval_add;
234       using default_ops::eval_get_sign;
235       using default_ops::eval_convert_to;
236       using default_ops::eval_subtract;
237 
238       typedef typename boost::multiprecision::detail::canonical<int, Float>::type f_int_type;
239       typedef typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type bf_int_type;
240 
241       switch(eval_fpclassify(f))
242       {
243       case FP_ZERO:
244          m_data = limb_type(0);
245          m_sign = ((boost::math::signbit)(f) > 0);
246          m_exponent = exponent_zero;
247          return *this;
248       case FP_NAN:
249          m_data = limb_type(0);
250          m_sign = false;
251          m_exponent = exponent_nan;
252          return *this;
253       case FP_INFINITE:
254          m_data = limb_type(0);
255          m_sign = (f < 0);
256          m_exponent = exponent_infinity;
257          return *this;
258       }
259       if(eval_get_sign(f) < 0)
260       {
261          f.negate();
262          *this = f;
263          this->negate();
264          return *this;
265       }
266 
267       typedef typename mpl::front<unsigned_types>::type ui_type;
268       m_data = static_cast<ui_type>(0u);
269       m_sign = false;
270       m_exponent = 0;
271 
272       static const int bits = sizeof(int) * CHAR_BIT - 1;
273       int e;
274       eval_frexp(f, f, &e);
275       while(eval_get_sign(f) != 0)
276       {
277          eval_ldexp(f, f, bits);
278          e -= bits;
279          int ipart;
280          eval_convert_to(&ipart, f);
281          eval_subtract(f, static_cast<f_int_type>(ipart));
282          m_exponent += bits;
283          eval_add(*this, static_cast<bf_int_type>(ipart));
284       }
285       m_exponent += e;
286       if(m_exponent > max_exponent)
287          m_exponent = exponent_infinity;
288       if(m_exponent < min_exponent)
289       {
290          m_data = limb_type(0u);
291          m_exponent = exponent_zero;
292          m_sign = ((boost::math::signbit)(f) > 0);
293       }
294       else if(eval_get_sign(m_data) == 0)
295       {
296          m_exponent = exponent_zero;
297          m_sign = ((boost::math::signbit)(f) > 0);
298       }
299       return *this;
300    }
301 
302    template <class I>
operator =(const I & i)303    typename boost::enable_if<is_integral<I>, cpp_bin_float&>::type operator=(const I& i)
304    {
305       using default_ops::eval_bit_test;
306       if(!i)
307       {
308          m_data = static_cast<limb_type>(0);
309          m_exponent = exponent_zero;
310          m_sign = false;
311       }
312       else
313       {
314          typedef typename make_unsigned<I>::type ui_type;
315          ui_type fi = static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(i));
316          typedef typename boost::multiprecision::detail::canonical<ui_type, rep_type>::type ar_type;
317          m_data = static_cast<ar_type>(fi);
318          unsigned shift = msb(fi);
319          if(shift >= bit_count)
320          {
321             m_exponent = static_cast<Exponent>(shift);
322             m_data = static_cast<ar_type>(fi >> (shift + 1 - bit_count));
323          }
324          else
325          {
326             m_exponent = static_cast<Exponent>(shift);
327             eval_left_shift(m_data, bit_count - shift - 1);
328          }
329          BOOST_ASSERT(eval_bit_test(m_data, bit_count-1));
330          m_sign = detail::is_negative(i);
331       }
332       return *this;
333    }
334 
335    cpp_bin_float& operator=(const char *s);
336 
swap(cpp_bin_float & o)337    void swap(cpp_bin_float &o) BOOST_NOEXCEPT
338    {
339       m_data.swap(o.m_data);
340       std::swap(m_exponent, o.m_exponent);
341       std::swap(m_sign, o.m_sign);
342    }
343 
344    std::string str(std::streamsize dig, std::ios_base::fmtflags f) const;
345 
negate()346    void negate()
347    {
348       if(m_exponent != exponent_nan)
349          m_sign = !m_sign;
350    }
351 
compare(const cpp_bin_float & o) const352    int compare(const cpp_bin_float &o) const BOOST_NOEXCEPT
353    {
354       if(m_sign != o.m_sign)
355          return (m_exponent == exponent_zero) && (m_exponent == o.m_exponent) ? 0 : m_sign ? -1 : 1;
356       int result;
357       if(m_exponent == exponent_nan)
358          return -1;
359       else if(m_exponent != o.m_exponent)
360       {
361          if(m_exponent == exponent_zero)
362             result = -1;
363          else if(o.m_exponent == exponent_zero)
364             result = 1;
365          else
366             result = m_exponent > o.m_exponent ? 1 : -1;
367       }
368       else
369          result = m_data.compare(o.m_data);
370       if(m_sign)
371          result = -result;
372       return result;
373    }
374    template <class A>
compare(const A & o) const375    int compare(const A& o) const BOOST_NOEXCEPT
376    {
377       cpp_bin_float b;
378       b = o;
379       return compare(b);
380    }
381 
bits()382    rep_type& bits() { return m_data; }
bits() const383    const rep_type& bits()const { return m_data; }
exponent()384    exponent_type& exponent() { return m_exponent; }
exponent() const385    const exponent_type& exponent()const { return m_exponent; }
sign()386    bool& sign() { return m_sign; }
sign() const387    const bool& sign()const { return m_sign; }
check_invariants()388    void check_invariants()
389    {
390       using default_ops::eval_bit_test;
391       using default_ops::eval_is_zero;
392       if((m_exponent <= max_exponent) && (m_exponent >= min_exponent))
393       {
394          BOOST_ASSERT(eval_bit_test(m_data, bit_count - 1));
395       }
396       else
397       {
398          BOOST_ASSERT(m_exponent > max_exponent);
399          BOOST_ASSERT(m_exponent <= exponent_nan);
400          BOOST_ASSERT(eval_is_zero(m_data));
401       }
402    }
403    template<class Archive>
serialize(Archive & ar,const unsigned int)404    void serialize(Archive & ar, const unsigned int /*version*/)
405    {
406       ar & m_data;
407       ar & m_exponent;
408       ar & m_sign;
409    }
410 };
411 
412 #ifdef BOOST_MSVC
413 #pragma warning(pop)
414 #endif
415 
416 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Int>
copy_and_round(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,Int & arg)417 inline void copy_and_round(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, Int &arg)
418 {
419    // Precondition: exponent of res must have been set before this function is called
420    // 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.
421    using default_ops::eval_msb;
422    using default_ops::eval_lsb;
423    using default_ops::eval_left_shift;
424    using default_ops::eval_bit_test;
425    using default_ops::eval_right_shift;
426    using default_ops::eval_increment;
427    using default_ops::eval_get_sign;
428 
429    // cancellation may have resulted in arg being all zeros:
430    if(eval_get_sign(arg) == 0)
431    {
432       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
433       res.sign() = false;
434       res.bits() = static_cast<limb_type>(0u);
435       return;
436    }
437    int msb = eval_msb(arg);
438    if(static_cast<int>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) > msb + 1)
439    {
440       // Must have had cancellation in subtraction, shift left and copy:
441       res.bits() = arg;
442       eval_left_shift(res.bits(), cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - msb - 1);
443       res.exponent() -= static_cast<Exponent>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - msb - 1);
444    }
445    else if(static_cast<int>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) < msb + 1)
446    {
447       // We have more cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than we need, so round as required,
448       // first get the rounding bit:
449       bool roundup = eval_bit_test(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count);
450       // Then check for a tie:
451       if(roundup && (msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count == eval_lsb(arg)))
452       {
453          // Ties round towards even:
454          if(!eval_bit_test(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1))
455             roundup = false;
456       }
457       // Shift off the cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count we don't need:
458       eval_right_shift(arg, msb - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1);
459       res.exponent() += static_cast<Exponent>(msb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1);
460       if(roundup)
461       {
462          eval_increment(arg);
463          if(eval_bit_test(arg, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
464          {
465             // This happens very very rairly:
466             eval_right_shift(arg, 1u);
467             ++res.exponent();
468          }
469       }
470       res.bits() = arg;
471    }
472    else
473    {
474       res.bits() = arg;
475    }
476    BOOST_ASSERT((eval_msb(res.bits()) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
477 
478    if(res.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
479    {
480       // Overflow:
481       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
482       res.bits() = static_cast<limb_type>(0u);
483    }
484    else if(res.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
485    {
486       // Underflow:
487       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
488       res.bits() = static_cast<limb_type>(0u);
489    }
490 }
491 
492 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
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)493 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)
494 {
495    if(a.exponent() < b.exponent())
496    {
497       bool s = a.sign();
498       do_eval_add(res, b, a);
499       if(res.sign() != s)
500          res.negate();
501       return;
502    }
503 
504    using default_ops::eval_add;
505    using default_ops::eval_bit_test;
506 
507    typedef typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type exponent_type;
508 
509    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
510 
511    // Special cases first:
512    switch(a.exponent())
513    {
514    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
515    {
516       bool s = a.sign();
517       res = b;
518       res.sign() = s;
519       return;
520    }
521    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
522       if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
523          res = b;
524       else
525          res = a;
526       return; // result is still infinite.
527    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
528       res = a;
529       return; // result is still a NaN.
530    }
531    switch(b.exponent())
532    {
533    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
534       res = a;
535       return;
536    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
537       res = b;
538       if(res.sign())
539          res.negate();
540       return; // result is infinite.
541    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
542       res = b;
543       return; // result is a NaN.
544    }
545 
546    BOOST_STATIC_ASSERT(boost::integer_traits<exponent_type>::const_max - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent);
547 
548    bool s = a.sign();
549    dt = a.bits();
550    if(a.exponent() > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + b.exponent())
551    {
552       res.exponent() = a.exponent();
553    }
554    else
555    {
556       exponent_type e_diff = a.exponent() - b.exponent();
557       BOOST_ASSERT(e_diff >= 0);
558       eval_left_shift(dt, e_diff);
559       res.exponent() = a.exponent() - e_diff;
560       eval_add(dt, b.bits());
561    }
562 
563    copy_and_round(res, dt);
564    res.check_invariants();
565    if(res.sign() != s)
566       res.negate();
567 }
568 
569 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
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)570 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)
571 {
572    using default_ops::eval_subtract;
573    using default_ops::eval_bit_test;
574 
575    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
576 
577    // Special cases first:
578    switch(a.exponent())
579    {
580    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
581       if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
582          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
583       else
584       {
585          bool s = a.sign();
586          res = b;
587          if(res.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero)
588             res.sign() = false;
589          else if(res.sign() == s)
590             res.negate();
591       }
592       return;
593    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
594       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))
595          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
596       else
597          res = a;
598       return;
599    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
600       res = a;
601       return; // result is still a NaN.
602    }
603    switch(b.exponent())
604    {
605    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
606       res = a;
607       return;
608    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
609       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
610       res.sign() = !a.sign();
611       res.bits() = static_cast<limb_type>(0u);
612       return; // result is a NaN.
613    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
614       res = b;
615       return; // result is still a NaN.
616    }
617 
618    bool s = a.sign();
619    if((a.exponent() > b.exponent()) || ((a.exponent() == b.exponent()) && a.bits().compare(b.bits()) >= 0))
620    {
621       dt = a.bits();
622       if(a.exponent() <= (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + b.exponent())
623       {
624          typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type e_diff = a.exponent() - b.exponent();
625          eval_left_shift(dt, e_diff);
626          res.exponent() = a.exponent() - e_diff;
627          eval_subtract(dt, b.bits());
628       }
629       else
630          res.exponent() = a.exponent();
631    }
632    else
633    {
634       dt = b.bits();
635       if(b.exponent() <= a.exponent() + (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
636       {
637          typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type e_diff = a.exponent() - b.exponent();
638          eval_left_shift(dt, -e_diff);
639          res.exponent() = b.exponent() + e_diff;
640          eval_subtract(dt, a.bits());
641       }
642       else
643          res.exponent() = b.exponent();
644       s = !s;
645    }
646 
647    copy_and_round(res, dt);
648    if(res.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero)
649       res.sign() = false;
650    else if(res.sign() != s)
651       res.negate();
652    res.check_invariants();
653 }
654 
655 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
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)656 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)
657 {
658    if(a.sign() == b.sign())
659       do_eval_add(res, a, b);
660    else
661       do_eval_subtract(res, a, b);
662 }
663 
664 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_add(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & a)665 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)
666 {
667    return eval_add(res, res, a);
668 }
669 
670 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
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)671 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)
672 {
673    if(a.sign() != b.sign())
674       do_eval_add(res, a, b);
675    else
676       do_eval_subtract(res, a, b);
677 }
678 
679 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_subtract(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & a)680 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)
681 {
682    return eval_subtract(res, res, a);
683 }
684 
685 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
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)686 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)
687 {
688    using default_ops::eval_bit_test;
689    using default_ops::eval_multiply;
690 
691    // Special cases first:
692    switch(a.exponent())
693    {
694    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
695    {
696       if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
697          res = b;
698       else if(b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity)
699          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
700       else
701       {
702          bool s = a.sign() != b.sign();
703          res = a;
704          res.sign() = s;
705       }
706       return;
707    }
708    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
709       switch(b.exponent())
710       {
711       case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
712          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
713          break;
714       case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
715          res = b;
716          break;
717       default:
718          bool s = a.sign() != b.sign();
719          res = a;
720          res.sign() = s;
721          break;
722       }
723       return;
724    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
725       res = a;
726       return;
727    }
728    if(b.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
729    {
730       bool s = a.sign() != b.sign();
731       res = b;
732       res.sign() = s;
733       return;
734    }
735    if((a.exponent() > 0) && (b.exponent() > 0))
736    {
737       if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + 2 - a.exponent() < b.exponent())
738       {
739          // We will certainly overflow:
740          bool s = a.sign() != b.sign();
741          res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
742          res.sign() = s;
743          res.bits() = static_cast<limb_type>(0u);
744          return;
745       }
746    }
747    if((a.exponent() < 0) && (b.exponent() < 0))
748    {
749       if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - 2 - a.exponent() > b.exponent())
750       {
751          // We will certainly underflow:
752          res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
753          res.sign() = a.sign() != b.sign();
754          res.bits() = static_cast<limb_type>(0u);
755          return;
756       }
757    }
758 
759    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
760    eval_multiply(dt, a.bits(), b.bits());
761    res.exponent() = a.exponent() + b.exponent() - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
762    copy_and_round(res, dt);
763    res.check_invariants();
764    res.sign() = a.sign() != b.sign();
765 }
766 
767 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_multiply(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & a)768 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)
769 {
770    eval_multiply(res, res, a);
771 }
772 
773 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
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)774 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)
775 {
776    using default_ops::eval_bit_test;
777    using default_ops::eval_multiply;
778 
779    // Special cases first:
780    switch(a.exponent())
781    {
782    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
783    {
784       bool s = a.sign();
785       res = a;
786       res.sign() = s;
787       return;
788    }
789    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
790       if(b == 0)
791          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
792       else
793          res = a;
794       return;
795    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
796       res = a;
797       return;
798    }
799 
800    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
801    typedef typename boost::multiprecision::detail::canonical<U, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::type canon_ui_type;
802    eval_multiply(dt, a.bits(), static_cast<canon_ui_type>(b));
803    res.exponent() = a.exponent();
804    copy_and_round(res, dt);
805    res.check_invariants();
806    res.sign() = a.sign();
807 }
808 
809 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
eval_multiply(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const U & b)810 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)
811 {
812    eval_multiply(res, res, b);
813 }
814 
815 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
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)816 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)
817 {
818    typedef typename make_unsigned<S>::type ui_type;
819    eval_multiply(res, a, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(b)));
820    if(b < 0)
821       res.negate();
822 }
823 
824 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
eval_multiply(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const S & b)825 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)
826 {
827    eval_multiply(res, res, b);
828 }
829 
830 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
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)831 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)
832 {
833 #ifdef BOOST_MSVC
834 #pragma warning(push)
835 #pragma warning(disable:6326)  // comparison of two constants
836 #endif
837    using default_ops::eval_subtract;
838    using default_ops::eval_qr;
839    using default_ops::eval_bit_test;
840    using default_ops::eval_get_sign;
841    using default_ops::eval_increment;
842 
843    //
844    // Special cases first:
845    //
846    switch(u.exponent())
847    {
848    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
849    {
850       switch(v.exponent())
851       {
852       case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
853       case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
854          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
855          return;
856       }
857       bool s = u.sign() != v.sign();
858       res = u;
859       res.sign() = s;
860       return;
861    }
862    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
863    {
864       switch(v.exponent())
865       {
866       case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
867       case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
868          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
869          return;
870       }
871       bool s = u.sign() != v.sign();
872       res = u;
873       res.sign() = s;
874       return;
875    }
876    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
877       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
878       return;
879    }
880    switch(v.exponent())
881    {
882    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
883       {
884       bool s = u.sign() != v.sign();
885       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
886       res.sign() = s;
887       return;
888       }
889    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
890       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
891       res.bits() = limb_type(0);
892       res.sign() = u.sign() != v.sign();
893       return;
894    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
895       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
896       return;
897    }
898 
899    // We can scale u and v so that both are integers, then perform integer
900    // division to obtain quotient q and remainder r, such that:
901    //
902    // q * v + r = u
903    //
904    // and hense:
905    //
906    // q + r/v = u/v
907    //
908    // From this, assuming q has cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count
909    // bits we only need to determine whether
910    // r/v is less than, equal to, or greater than 0.5 to determine rounding -
911    // this we can do with a shift and comparison.
912    //
913    // We can set the exponent and sign of the result up front:
914    //
915    if((v.exponent() < 0) && (u.exponent() > 0))
916    {
917       // Check for overflow:
918       if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + v.exponent() < u.exponent() - 1)
919       {
920          res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
921          res.sign() = u.sign() != v.sign();
922          res.bits() = static_cast<limb_type>(0u);
923          return;
924       }
925    }
926    else if((v.exponent() > 0) && (u.exponent() < 0))
927    {
928       // Check for underflow:
929       if(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent + v.exponent() > u.exponent())
930       {
931          // We will certainly underflow:
932          res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
933          res.sign() = u.sign() != v.sign();
934          res.bits() = static_cast<limb_type>(0u);
935          return;
936       }
937    }
938    res.exponent() = u.exponent() - v.exponent() - 1;
939    res.sign() = u.sign() != v.sign();
940    //
941    // Now get the quotient and remainder:
942    //
943    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), t2(v.bits()), q, r;
944    eval_left_shift(t, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count);
945    eval_qr(t, t2, q, r);
946    //
947    // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count"
948    // or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant
949    // bits in q.
950    //
951    static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
952    if(eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
953    {
954       //
955       // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 bits,
956       // so we already have rounding info,
957       // we just need to changes things if the last bit is 1 and either the
958       // remainder is non-zero (ie we do not have a tie) or the quotient would
959       // be odd if it were shifted to the correct number of bits (ie a tiebreak).
960       //
961       BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
962       if((q.limbs()[0] & 1u) && (eval_get_sign(r) || (q.limbs()[0] & 2u)))
963       {
964          eval_increment(q);
965       }
966    }
967    else
968    {
969       //
970       // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" bits in q.
971       // Get rounding info, which we can get by comparing 2r with v.
972       // We want to call copy_and_round to handle rounding and general cleanup,
973       // so we'll left shift q and add some fake digits on the end to represent
974       // how we'll be rounding.
975       //
976       BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
977       static const unsigned lshift = (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits) ? 2 : limb_bits;
978       eval_left_shift(q, lshift);
979       res.exponent() -= lshift;
980       eval_left_shift(r, 1u);
981       int c = r.compare(v.bits());
982       if(c == 0)
983          q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
984       else if(c > 0)
985          q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
986    }
987    copy_and_round(res, q);
988 #ifdef BOOST_MSVC
989 #pragma warning(pop)
990 #endif
991 }
992 
993 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_divide(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)994 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)
995 {
996    eval_divide(res, res, arg);
997 }
998 
999 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
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)1000 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)
1001 {
1002 #ifdef BOOST_MSVC
1003 #pragma warning(push)
1004 #pragma warning(disable:6326)  // comparison of two constants
1005 #endif
1006    using default_ops::eval_subtract;
1007    using default_ops::eval_qr;
1008    using default_ops::eval_bit_test;
1009    using default_ops::eval_get_sign;
1010    using default_ops::eval_increment;
1011 
1012    //
1013    // Special cases first:
1014    //
1015    switch(u.exponent())
1016    {
1017    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1018    {
1019       if(v == 0)
1020       {
1021          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1022          return;
1023       }
1024       bool s = u.sign() != (v < 0);
1025       res = u;
1026       res.sign() = s;
1027       return;
1028    }
1029    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1030       res = u;
1031       return;
1032    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1033       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1034       return;
1035    }
1036    if(v == 0)
1037    {
1038       bool s = u.sign();
1039       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1040       res.sign() = s;
1041       return;
1042    }
1043 
1044    // We can scale u and v so that both are integers, then perform integer
1045    // division to obtain quotient q and remainder r, such that:
1046    //
1047    // q * v + r = u
1048    //
1049    // and hense:
1050    //
1051    // q + r/v = u/v
1052    //
1053    // 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
1054    // r/v is less than, equal to, or greater than 0.5 to determine rounding -
1055    // this we can do with a shift and comparison.
1056    //
1057    // We can set the exponent and sign of the result up front:
1058    //
1059    int gb = msb(v);
1060    res.exponent() = u.exponent() - static_cast<Exponent>(gb) - static_cast<Exponent>(1);
1061    res.sign() = u.sign();
1062    //
1063    // Now get the quotient and remainder:
1064    //
1065    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), q, r;
1066    eval_left_shift(t, gb + 1);
1067    eval_qr(t, number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v), q, r);
1068    //
1069    // 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.
1070    //
1071    static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
1072    if(eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
1073    {
1074       //
1075       // 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,
1076       // we just need to changes things if the last bit is 1 and the
1077       // remainder is non-zero (ie we do not have a tie).
1078       //
1079       BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
1080       if((q.limbs()[0] & 1u) && eval_get_sign(r))
1081       {
1082          eval_increment(q);
1083       }
1084    }
1085    else
1086    {
1087       //
1088       // 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.
1089       // Get rounding info, which we can get by comparing 2r with v.
1090       // We want to call copy_and_round to handle rounding and general cleanup,
1091       // 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
1092       // how we'll be rounding.
1093       //
1094       BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
1095       static const unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits;
1096       eval_left_shift(q, lshift);
1097       res.exponent() -= lshift;
1098       eval_left_shift(r, 1u);
1099       int c = r.compare(number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v));
1100       if(c == 0)
1101          q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
1102       else if(c > 0)
1103          q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
1104    }
1105    copy_and_round(res, q);
1106 #ifdef BOOST_MSVC
1107 #pragma warning(pop)
1108 #endif
1109 }
1110 
1111 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
eval_divide(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const U & v)1112 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)
1113 {
1114    eval_divide(res, res, v);
1115 }
1116 
1117 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
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)1118 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)
1119 {
1120    typedef typename make_unsigned<S>::type ui_type;
1121    eval_divide(res, u, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(v)));
1122    if(v < 0)
1123       res.negate();
1124 }
1125 
1126 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
eval_divide(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const S & v)1127 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)
1128 {
1129    eval_divide(res, res, v);
1130 }
1131 
1132 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_get_sign(const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1133 inline int eval_get_sign(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
1134 {
1135    return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero ? 0 : arg.sign() ? -1 : 1;
1136 }
1137 
1138 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_is_zero(const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1139 inline bool eval_is_zero(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
1140 {
1141    return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1142 }
1143 
1144 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_eq(const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & a,cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & b)1145 inline bool eval_eq(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &a, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &b)
1146 {
1147    if(a.exponent() == b.exponent())
1148    {
1149       if(a.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero)
1150          return true;
1151       return (a.sign() == b.sign())
1152          && (a.bits().compare(b.bits()) == 0)
1153          && (a.exponent() != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan);
1154    }
1155    return false;
1156 }
1157 
1158 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_convert_to(boost::long_long_type * res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1159 inline void eval_convert_to(boost::long_long_type *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
1160 {
1161    switch(arg.exponent())
1162    {
1163    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1164       *res = 0;
1165       return;
1166    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1167       BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1168    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1169       *res = (std::numeric_limits<boost::long_long_type>::max)();
1170       if(arg.sign())
1171          *res = -*res;
1172       return;
1173    }
1174    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
1175    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
1176       = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
1177    if(shift > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
1178    {
1179       *res = 0;
1180       return;
1181    }
1182    if(arg.sign() && (arg.compare((std::numeric_limits<boost::long_long_type>::min)()) <= 0))
1183    {
1184       *res = (std::numeric_limits<boost::long_long_type>::min)();
1185       return;
1186    }
1187    else if(!arg.sign() && (arg.compare((std::numeric_limits<boost::long_long_type>::max)()) >= 0))
1188    {
1189       *res = (std::numeric_limits<boost::long_long_type>::max)();
1190       return;
1191    }
1192    eval_right_shift(man, shift);
1193    eval_convert_to(res, man);
1194    if(arg.sign())
1195    {
1196       *res = -*res;
1197    }
1198 }
1199 
1200 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_convert_to(boost::ulong_long_type * res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1201 inline void eval_convert_to(boost::ulong_long_type *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
1202 {
1203    switch(arg.exponent())
1204    {
1205    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1206       *res = 0;
1207       return;
1208    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1209       BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1210    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1211       *res = (std::numeric_limits<boost::ulong_long_type>::max)();
1212       return;
1213    }
1214    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
1215    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
1216       = (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
1217    if(shift > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
1218    {
1219       *res = 0;
1220       return;
1221    }
1222    else if(shift < 0)
1223    {
1224       // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than a boost::long_long_type?
1225       *res = (std::numeric_limits<boost::long_long_type>::max)();
1226       return;
1227    }
1228    eval_right_shift(man, shift);
1229    eval_convert_to(res, man);
1230 }
1231 
1232 template <class Float, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_convert_to(Float * res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & original_arg)1233 inline typename boost::enable_if_c<boost::is_float<Float>::value>::type eval_convert_to(Float *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &original_arg)
1234 {
1235    //
1236    // Perform rounding first, then afterwards extract the digits:
1237    //
1238    typedef cpp_bin_float<std::numeric_limits<Float>::digits, digit_base_2, void, Exponent, MinE, MaxE>  conv_type;
1239    typedef typename common_type<typename conv_type::exponent_type, int>::type                           common_exp_type;
1240    conv_type arg(original_arg);
1241    switch(arg.exponent())
1242    {
1243    case conv_type::exponent_zero:
1244       *res = 0;
1245       if(arg.sign())
1246          *res = -*res;
1247       return;
1248    case conv_type::exponent_nan:
1249       *res = std::numeric_limits<Float>::quiet_NaN();
1250       return;
1251    case conv_type::exponent_infinity:
1252       *res = (std::numeric_limits<Float>::infinity)();
1253       if(arg.sign())
1254          *res = -*res;
1255       return;
1256    }
1257    common_exp_type e = arg.exponent();
1258    static const common_exp_type min_exp_limit = std::numeric_limits<Float>::min_exponent
1259       - (common_exp_type)cpp_bin_float<std::numeric_limits<Float>::digits, digit_base_2, void, Exponent, MinE, MaxE>::bit_count - std::numeric_limits<Float>::digits - 2;
1260    e -= cpp_bin_float<std::numeric_limits<Float>::digits, digit_base_2, void, Exponent, MinE, MaxE>::bit_count - 1;
1261    if(e < min_exp_limit)
1262    {
1263       *res = 0;
1264       return;
1265    }
1266    if(e > std::numeric_limits<Float>::max_exponent)
1267    {
1268       *res = std::numeric_limits<Float>::has_infinity ? std::numeric_limits<Float>::infinity() : (std::numeric_limits<Float>::max)();
1269       return;
1270    }
1271 
1272    *res = std::ldexp(static_cast<Float>(*arg.bits().limbs()), static_cast<int>(e));
1273    for(unsigned i = 1; i < arg.bits().size(); ++i)
1274    {
1275       e += sizeof(*arg.bits().limbs()) * CHAR_BIT;
1276       *res += std::ldexp(static_cast<Float>(arg.bits().limbs()[i]), static_cast<int>(e));
1277    }
1278    if(arg.sign())
1279       *res = -*res;
1280 }
1281 
1282 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
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)1283 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)
1284 {
1285    switch(arg.exponent())
1286    {
1287    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1288    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1289    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1290       *e = 0;
1291       res = arg;
1292       return;
1293    }
1294    res = arg;
1295    *e = arg.exponent() + 1;
1296    res.exponent() = -1;
1297 }
1298 
1299 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
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)1300 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)
1301 {
1302    Exponent e;
1303    eval_frexp(res, arg, &e);
1304    if((e > (std::numeric_limits<I>::max)()) || (e < (std::numeric_limits<I>::min)()))
1305    {
1306       BOOST_THROW_EXCEPTION(std::runtime_error("Exponent was outside of the range of the argument type to frexp."));
1307    }
1308    *pe = static_cast<I>(e);
1309 }
1310 
1311 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
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)1312 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)
1313 {
1314    switch(arg.exponent())
1315    {
1316    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1317    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1318    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1319       res = arg;
1320       return;
1321    }
1322    if((e > 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent - e < arg.exponent()))
1323    {
1324       // Overflow:
1325       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1326       res.sign() = arg.sign();
1327    }
1328    else if((e < 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - e > arg.exponent()))
1329    {
1330       // Underflow:
1331       res = limb_type(0);
1332    }
1333    else
1334    {
1335       res = arg;
1336       res.exponent() += e;
1337    }
1338 }
1339 
1340 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
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)1341 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)
1342 {
1343    typedef typename make_signed<I>::type si_type;
1344    if(e > static_cast<I>((std::numeric_limits<si_type>::max)()))
1345       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1346    else
1347       eval_ldexp(res, arg, static_cast<si_type>(e));
1348 }
1349 
1350 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
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)1351 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)
1352 {
1353    if((e > (std::numeric_limits<Exponent>::max)()) || (e < (std::numeric_limits<Exponent>::min)()))
1354    {
1355       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1356       if(e < 0)
1357          res.negate();
1358    }
1359    else
1360       eval_ldexp(res, arg, static_cast<Exponent>(e));
1361 }
1362 
1363 /*
1364 * Sign manipulation
1365 */
1366 
1367 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_abs(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1368 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)
1369 {
1370    res = arg;
1371    res.sign() = false;
1372 }
1373 
1374 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_fabs(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1375 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)
1376 {
1377    res = arg;
1378    res.sign() = false;
1379 }
1380 
1381 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_fpclassify(const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1382 inline int eval_fpclassify(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
1383 {
1384    switch(arg.exponent())
1385    {
1386    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1387       return FP_ZERO;
1388    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1389       return FP_INFINITE;
1390    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1391       return FP_NAN;
1392    }
1393    return FP_NORMAL;
1394 }
1395 
1396 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_sqrt(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1397 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)
1398 {
1399    using default_ops::eval_integer_sqrt;
1400    using default_ops::eval_bit_test;
1401    using default_ops::eval_increment;
1402    switch(arg.exponent())
1403    {
1404    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1405    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1406       res = arg;
1407       return;
1408    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1409       if(arg.sign())
1410          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1411       else
1412          res = arg;
1413       return;
1414    }
1415    if(arg.sign())
1416    {
1417       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1418       return;
1419    }
1420 
1421    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(arg.bits()), r, s;
1422    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);
1423    eval_integer_sqrt(s, r, t);
1424 
1425    if(!eval_bit_test(s, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
1426    {
1427       // We have exactly the right number of cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in the result, round as required:
1428       if(s.compare(r) < 0)
1429       {
1430          eval_increment(s);
1431       }
1432    }
1433    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type ae = arg.exponent();
1434    res.exponent() = ae / 2;
1435    if((ae & 1) && (ae < 0))
1436       --res.exponent();
1437    copy_and_round(res, s);
1438 }
1439 
1440 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_floor(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1441 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)
1442 {
1443    using default_ops::eval_increment;
1444    switch(arg.exponent())
1445    {
1446    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1447    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1448    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1449       res = arg;
1450       return;
1451    }
1452    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 =
1453       (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
1454    if((arg.exponent() > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
1455    {
1456       // Either arg is already an integer, or a special value:
1457       res = arg;
1458       return;
1459    }
1460    if(shift >= (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
1461    {
1462       res = static_cast<signed_limb_type>(arg.sign() ? -1 : 0);
1463       return;
1464    }
1465    bool fractional = (int)eval_lsb(arg.bits()) < shift;
1466    res = arg;
1467    eval_right_shift(res.bits(), shift);
1468    if(fractional && res.sign())
1469    {
1470       eval_increment(res.bits());
1471       if(eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift)
1472       {
1473          // Must have extended result by one bit in the increment:
1474          --shift;
1475          ++res.exponent();
1476       }
1477    }
1478    eval_left_shift(res.bits(), shift);
1479 }
1480 
1481 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
eval_ceil(cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & res,const cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE> & arg)1482 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)
1483 {
1484    using default_ops::eval_increment;
1485    switch(arg.exponent())
1486    {
1487    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1488    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1489    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1490       res = arg;
1491       return;
1492    }
1493    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;
1494    if((arg.exponent() > (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
1495    {
1496       // Either arg is already an integer, or a special value:
1497       res = arg;
1498       return;
1499    }
1500    if(shift >= (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
1501    {
1502       bool s = arg.sign(); // takes care of signed zeros
1503       res = static_cast<signed_limb_type>(arg.sign() ? 0 : 1);
1504       res.sign() = s;
1505       return;
1506    }
1507    bool fractional = (int)eval_lsb(arg.bits()) < shift;
1508    res = arg;
1509    eval_right_shift(res.bits(), shift);
1510    if(fractional && !res.sign())
1511    {
1512       eval_increment(res.bits());
1513       if(eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift)
1514       {
1515          // Must have extended result by one bit in the increment:
1516          --shift;
1517          ++res.exponent();
1518       }
1519    }
1520    eval_left_shift(res.bits(), shift);
1521 }
1522 
1523 template<unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2>
hash_value(const cpp_bin_float<D1,B1,A1,E1,M1,M2> & val)1524 inline std::size_t hash_value(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val)
1525 {
1526    std::size_t result = hash_value(val.bits());
1527    boost::hash_combine(result, val.exponent());
1528    boost::hash_combine(result, val.sign());
1529    return result;
1530 }
1531 
1532 
1533 } // namespace backends
1534 
1535 #ifdef BOOST_NO_SFINAE_EXPR
1536 
1537 namespace detail{
1538 
1539 template<unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2, unsigned D2, backends::digit_base_type B2, class A2, class E2, E2 M3, E2 M4>
1540 struct is_explicitly_convertible<backends::cpp_bin_float<D1, B1, A1, E1, M1, M2>, backends::cpp_bin_float<D2, B2, A2, E2, M3, M4> > : public mpl::true_ {};
1541 template<class FloatT, unsigned D2, backends::digit_base_type B2, class A2, class E2, E2 M3, E2 M4>
1542 struct is_explicitly_convertible<FloatT, backends::cpp_bin_float<D2, B2, A2, E2, M3, M4> > : public boost::is_floating_point<FloatT> {};
1543 
1544 }
1545 #endif
1546 
1547 template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE>,ExpressionTemplates> & arg)1548 inline int signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& arg)
1549 {
1550    return arg.backend().sign();
1551 }
1552 
1553 template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
1554 inline boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE>,ExpressionTemplates> & a,const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits,DigitBase,Allocator,Exponent,MinE,MaxE>,ExpressionTemplates> & b)1555 copysign BOOST_PREVENT_MACRO_SUBSTITUTION(
1556    const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& a,
1557    const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& b)
1558 {
1559    boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> res(a);
1560    res.backend().sign() = b.backend().sign();
1561    return res;
1562 }
1563 
1564 using backends::cpp_bin_float;
1565 using backends::digit_base_2;
1566 using backends::digit_base_10;
1567 
1568 template<unsigned Digits, backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator>
1569 struct number_category<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > : public boost::mpl::int_<boost::multiprecision::number_kind_floating_point>{};
1570 
1571 template<unsigned Digits, backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1572 struct expression_template_default<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> >
1573 {
1574    static const expression_template_option value = is_void<Allocator>::value ? et_off : et_on;
1575 };
1576 
1577 typedef number<backends::cpp_bin_float<50> > cpp_bin_float_50;
1578 typedef number<backends::cpp_bin_float<100> > cpp_bin_float_100;
1579 
1580 typedef number<backends::cpp_bin_float<24, backends::digit_base_2, void, boost::int16_t, -126, 127>, et_off> cpp_bin_float_single;
1581 typedef number<backends::cpp_bin_float<53, backends::digit_base_2, void, boost::int16_t, -1022, 1023>, et_off> cpp_bin_float_double;
1582 typedef number<backends::cpp_bin_float<64, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_double_extended;
1583 typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_quad;
1584 
1585 } // namespace multiprecision
1586 
1587 namespace math {
1588 
1589    using boost::multiprecision::signbit;
1590    using boost::multiprecision::copysign;
1591 
1592 } // namespace math
1593 
1594 } // namespace boost
1595 
1596 #include <boost/multiprecision/cpp_bin_float/io.hpp>
1597 #include <boost/multiprecision/cpp_bin_float/transcendental.hpp>
1598 
1599 namespace std{
1600 
1601 //
1602 // numeric_limits [partial] specializations for the types declared in this header:
1603 //
1604 template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1605 class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >
1606 {
1607    typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> number_type;
1608 public:
1609    BOOST_STATIC_CONSTEXPR bool is_specialized = true;
number_type(min)1610    static number_type (min)()
1611    {
1612       initializer.do_nothing();
1613       static std::pair<bool, number_type> value;
1614       if(!value.first)
1615       {
1616          value.first = true;
1617          value.second = 1u;
1618          value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
1619       }
1620       return value.second;
1621    }
number_type(max)1622    static number_type (max)()
1623    {
1624       initializer.do_nothing();
1625       static std::pair<bool, number_type> value;
1626       if(!value.first)
1627       {
1628          value.first = true;
1629          eval_complement(value.second.backend().bits(), value.second.backend().bits());
1630          value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
1631       }
1632       return value.second;
1633    }
lowest()1634    BOOST_STATIC_CONSTEXPR number_type lowest()
1635    {
1636       return -(max)();
1637    }
1638    BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count;
1639    BOOST_STATIC_CONSTEXPR int digits10 = (digits - 1) * 301 / 1000;
1640    // Is this really correct???
1641    BOOST_STATIC_CONSTEXPR int max_digits10 = (digits * 301 / 1000) + 3;
1642    BOOST_STATIC_CONSTEXPR bool is_signed = true;
1643    BOOST_STATIC_CONSTEXPR bool is_integer = false;
1644    BOOST_STATIC_CONSTEXPR bool is_exact = false;
1645    BOOST_STATIC_CONSTEXPR int radix = 2;
epsilon()1646    static number_type epsilon()
1647    {
1648       initializer.do_nothing();
1649       static std::pair<bool, number_type> value;
1650       if(!value.first)
1651       {
1652          value.first = true;
1653          value.second = 1;
1654          value.second = ldexp(value.second, 1 - (int)digits);
1655       }
1656       return value.second;
1657    }
1658    // What value should this be????
round_error()1659    static number_type round_error()
1660    {
1661       // returns 0.5
1662       initializer.do_nothing();
1663       static std::pair<bool, number_type> value;
1664       if(!value.first)
1665       {
1666          value.first = true;
1667          value.second = 1;
1668          value.second = ldexp(value.second, -1);
1669       }
1670       return value.second;
1671    }
1672    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;
1673    BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent10 = (min_exponent / 1000) * 301L;
1674    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;
1675    BOOST_STATIC_CONSTEXPR typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent10 = (max_exponent / 1000) * 301L;
1676    BOOST_STATIC_CONSTEXPR bool has_infinity = true;
1677    BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
1678    BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
1679    BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
1680    BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
infinity()1681    static number_type infinity()
1682    {
1683       initializer.do_nothing();
1684       static std::pair<bool, number_type> value;
1685       if(!value.first)
1686       {
1687          value.first = true;
1688          value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
1689       }
1690       return value.second;
1691    }
quiet_NaN()1692    static number_type quiet_NaN()
1693    {
1694       initializer.do_nothing();
1695       static std::pair<bool, number_type> value;
1696       if(!value.first)
1697       {
1698          value.first = true;
1699          value.second.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan;
1700       }
1701       return value.second;
1702    }
signaling_NaN()1703    BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
1704    {
1705       return number_type(0);
1706    }
denorm_min()1707    BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
1708    BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
1709    BOOST_STATIC_CONSTEXPR bool is_bounded = true;
1710    BOOST_STATIC_CONSTEXPR bool is_modulo = false;
1711    BOOST_STATIC_CONSTEXPR bool traps = true;
1712    BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
1713    BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
1714 private:
1715    struct data_initializer
1716    {
data_initializerstd::numeric_limits::data_initializer1717       data_initializer()
1718       {
1719          std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::epsilon();
1720          std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::round_error();
1721          (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::min)();
1722          (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::max)();
1723          std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity();
1724          std::numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN();
1725       }
do_nothingstd::numeric_limits::data_initializer1726       void do_nothing()const{}
1727    };
1728    static const data_initializer initializer;
1729 };
1730 
1731 template<unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1732 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;
1733 
1734 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
1735 
1736 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1737 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits;
1738 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1739 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits10;
1740 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1741 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_digits10;
1742 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1743 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_signed;
1744 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1745 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_integer;
1746 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1747 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_exact;
1748 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1749 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::radix;
1750 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1751 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;
1752 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1753 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;
1754 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1755 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;
1756 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1757 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;
1758 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1759 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_infinity;
1760 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1761 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;
1762 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1763 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;
1764 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1765 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;
1766 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1767 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;
1768 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1769 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_iec559;
1770 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1771 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_bounded;
1772 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1773 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_modulo;
1774 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1775 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::traps;
1776 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1777 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::tinyness_before;
1778 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
1779 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;
1780 
1781 #endif
1782 
1783 } // namespace std
1784 
1785 #endif
1786