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