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