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