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