1///////////////////////////////////////////////////////////////////////////////
2// Copyright Christopher Kormanyos 2002 - 2013.
3// Copyright 2011 -2013 John Maddock. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// This work is based on an earlier work:
8// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations",
9// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469
10//
11// Note that there are no "noexcept" specifications on the functions in this file: there are too many
12// calls to lexical_cast (and similar) to easily analyse the code for correctness. So until compilers
13// can detect noexcept misuse at compile time, the only realistic option is to simply not use it here.
14//
15
16#ifndef BOOST_MP_CPP_DEC_FLOAT_BACKEND_HPP
17#define BOOST_MP_CPP_DEC_FLOAT_BACKEND_HPP
18
19#include <boost/config.hpp>
20#include <boost/cstdint.hpp>
21#include <limits>
22#ifndef BOOST_NO_CXX11_HDR_ARRAY
23#include <array>
24#else
25#include <boost/array.hpp>
26#endif
27#include <boost/cstdint.hpp>
28#include <boost/multiprecision/number.hpp>
29#include <boost/multiprecision/detail/big_lanczos.hpp>
30#include <boost/multiprecision/detail/dynamic_array.hpp>
31
32//
33// Headers required for Boost.Math integration:
34//
35#include <boost/math/policies/policy.hpp>
36
37#ifdef BOOST_MSVC
38#pragma warning(push)
39#pragma warning(disable:6326) // comparison of two constants
40#endif
41
42namespace boost{
43namespace multiprecision{
44namespace backends{
45
46template <unsigned Digits10, class ExponentType = boost::int32_t, class Allocator = void>
47class cpp_dec_float;
48
49} // namespace
50
51template <unsigned Digits10, class ExponentType, class Allocator>
52struct number_category<backends::cpp_dec_float<Digits10, ExponentType, Allocator> > : public mpl::int_<number_kind_floating_point>{};
53
54namespace backends{
55
56template <unsigned Digits10, class ExponentType, class Allocator>
57class cpp_dec_float
58{
59private:
60 static const boost::int32_t cpp_dec_float_digits10_setting = Digits10;
61
62 // We need at least 16-bits in the exponent type to do anything sensible:
63 BOOST_STATIC_ASSERT_MSG(boost::is_signed<ExponentType>::value, "ExponentType must be a signed built in integer type.");
64 BOOST_STATIC_ASSERT_MSG(sizeof(ExponentType) > 1, "ExponentType is too small.");
65
66public:
67 typedef mpl::list<boost::long_long_type> signed_types;
68 typedef mpl::list<boost::ulong_long_type> unsigned_types;
69 typedef mpl::list<long double> float_types;
70 typedef ExponentType exponent_type;
71
72 static const boost::int32_t cpp_dec_float_radix = 10L;
73 static const boost::int32_t cpp_dec_float_digits10_limit_lo = 9L;
74 static const boost::int32_t cpp_dec_float_digits10_limit_hi = boost::integer_traits<boost::int32_t>::const_max - 100;
75 static const boost::int32_t cpp_dec_float_digits10 = ((cpp_dec_float_digits10_setting < cpp_dec_float_digits10_limit_lo) ? cpp_dec_float_digits10_limit_lo : ((cpp_dec_float_digits10_setting > cpp_dec_float_digits10_limit_hi) ? cpp_dec_float_digits10_limit_hi : cpp_dec_float_digits10_setting));
76 static const ExponentType cpp_dec_float_max_exp10 = (static_cast<ExponentType>(1) << (std::numeric_limits<ExponentType>::digits - 5));
77 static const ExponentType cpp_dec_float_min_exp10 = -cpp_dec_float_max_exp10;
78 static const ExponentType cpp_dec_float_max_exp = cpp_dec_float_max_exp10;
79 static const ExponentType cpp_dec_float_min_exp = cpp_dec_float_min_exp10;
80
81 BOOST_STATIC_ASSERT((cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10 == -cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10));
82
83private:
84 static const boost::int32_t cpp_dec_float_elem_digits10 = 8L;
85 static const boost::int32_t cpp_dec_float_elem_mask = 100000000L;
86
87 BOOST_STATIC_ASSERT(0 == cpp_dec_float_max_exp10 % cpp_dec_float_elem_digits10);
88
89 // There are three guard limbs.
90 // 1) The first limb has 'play' from 1...8 decimal digits.
91 // 2) The last limb also has 'play' from 1...8 decimal digits.
92 // 3) One limb can get lost when justifying after multiply,
93 // as only half of the triangle is multiplied and a carry
94 // from below is missing.
95 static const boost::int32_t cpp_dec_float_elem_number_request = static_cast<boost::int32_t>((cpp_dec_float_digits10 / cpp_dec_float_elem_digits10) + (((cpp_dec_float_digits10 % cpp_dec_float_elem_digits10) != 0) ? 1 : 0));
96
97 // The number of elements needed (with a minimum of two) plus three added guard limbs.
98 static const boost::int32_t cpp_dec_float_elem_number = static_cast<boost::int32_t>(((cpp_dec_float_elem_number_request < 2L) ? 2L : cpp_dec_float_elem_number_request) + 3L);
99
100public:
101 static const boost::int32_t cpp_dec_float_total_digits10 = static_cast<boost::int32_t>(cpp_dec_float_elem_number * cpp_dec_float_elem_digits10);
102
103private:
104
105 typedef enum enum_fpclass_type
106 {
107 cpp_dec_float_finite,
108 cpp_dec_float_inf,
109 cpp_dec_float_NaN
110 }
111 fpclass_type;
112
113#ifndef BOOST_NO_CXX11_HDR_ARRAY
114 typedef typename mpl::if_<is_void<Allocator>,
115 std::array<boost::uint32_t, cpp_dec_float_elem_number>,
116 detail::dynamic_array<boost::uint32_t, cpp_dec_float_elem_number, Allocator>
117 >::type array_type;
118#else
119 typedef typename mpl::if_<is_void<Allocator>,
120 boost::array<boost::uint32_t, cpp_dec_float_elem_number>,
121 detail::dynamic_array<boost::uint32_t, cpp_dec_float_elem_number, Allocator>
122 >::type array_type;
123#endif
124
125 array_type data;
126 ExponentType exp;
127 bool neg;
128 fpclass_type fpclass;
129 boost::int32_t prec_elem;
130
131 //
132 // Special values constructor:
133 //
134 cpp_dec_float(fpclass_type c) :
135 data(),
136 exp (static_cast<ExponentType>(0)),
137 neg (false),
138 fpclass (c),
139 prec_elem(cpp_dec_float_elem_number) { }
140
141 //
142 // Static data initializer:
143 //
144 struct initializer
145 {
146 initializer()
147 {
148 cpp_dec_float<Digits10, ExponentType, Allocator>::nan();
149 cpp_dec_float<Digits10, ExponentType, Allocator>::inf();
150 (cpp_dec_float<Digits10, ExponentType, Allocator>::min)();
151 (cpp_dec_float<Digits10, ExponentType, Allocator>::max)();
152 cpp_dec_float<Digits10, ExponentType, Allocator>::zero();
153 cpp_dec_float<Digits10, ExponentType, Allocator>::one();
154 cpp_dec_float<Digits10, ExponentType, Allocator>::two();
155 cpp_dec_float<Digits10, ExponentType, Allocator>::half();
156 cpp_dec_float<Digits10, ExponentType, Allocator>::double_min();
157 cpp_dec_float<Digits10, ExponentType, Allocator>::double_max();
158 cpp_dec_float<Digits10, ExponentType, Allocator>::long_double_max();
159 cpp_dec_float<Digits10, ExponentType, Allocator>::long_double_min();
160 cpp_dec_float<Digits10, ExponentType, Allocator>::long_long_max();
161 cpp_dec_float<Digits10, ExponentType, Allocator>::long_long_min();
162 cpp_dec_float<Digits10, ExponentType, Allocator>::ulong_long_max();
163 cpp_dec_float<Digits10, ExponentType, Allocator>::eps();
164 cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(i: 0);
165 }
166 void do_nothing(){}
167 };
168
169 static initializer init;
170
171public:
172 // Constructors
173 cpp_dec_float() BOOST_MP_NOEXCEPT_IF(noexcept(array_type())) :
174 data(),
175 exp (static_cast<ExponentType>(0)),
176 neg (false),
177 fpclass (cpp_dec_float_finite),
178 prec_elem(cpp_dec_float_elem_number) { }
179
180 cpp_dec_float(const char* s) :
181 data(),
182 exp (static_cast<ExponentType>(0)),
183 neg (false),
184 fpclass (cpp_dec_float_finite),
185 prec_elem(cpp_dec_float_elem_number)
186 {
187 *this = s;
188 }
189
190 template<class I>
191 cpp_dec_float(I i, typename enable_if<is_unsigned<I> >::type* = 0) :
192 data(),
193 exp (static_cast<ExponentType>(0)),
194 neg (false),
195 fpclass (cpp_dec_float_finite),
196 prec_elem(cpp_dec_float_elem_number)
197 {
198 from_unsigned_long_long(u: i);
199 }
200
201 template <class I>
202 cpp_dec_float(I i, typename enable_if<is_signed<I> >::type* = 0) :
203 data(),
204 exp (static_cast<ExponentType>(0)),
205 neg (false),
206 fpclass (cpp_dec_float_finite),
207 prec_elem(cpp_dec_float_elem_number)
208 {
209 if(i < 0)
210 {
211 from_unsigned_long_long(u: boost::multiprecision::detail::unsigned_abs(i));
212 negate();
213 }
214 else
215 from_unsigned_long_long(u: i);
216 }
217
218 cpp_dec_float(const cpp_dec_float& f) BOOST_MP_NOEXCEPT_IF(noexcept(array_type(std::declval<const array_type&>()))) :
219 data (f.data),
220 exp (f.exp),
221 neg (f.neg),
222 fpclass (f.fpclass),
223 prec_elem(f.prec_elem) { }
224
225 template <unsigned D, class ET, class A>
226 cpp_dec_float(const cpp_dec_float<D, ET, A>& f, typename enable_if_c<D <= Digits10>::type* = 0) :
227 data(),
228 exp (f.exp),
229 neg (f.neg),
230 fpclass (static_cast<fpclass_type>(static_cast<int>(f.fpclass))),
231 prec_elem(cpp_dec_float_elem_number)
232 {
233 std::copy(f.data.begin(), f.data.begin() + f.prec_elem, data.begin());
234 }
235 template <unsigned D, class ET, class A>
236 explicit cpp_dec_float(const cpp_dec_float<D, ET, A>& f, typename disable_if_c<D <= Digits10>::type* = 0) :
237 data(),
238 exp (f.exp),
239 neg (f.neg),
240 fpclass (static_cast<fpclass_type>(static_cast<int>(f.fpclass))),
241 prec_elem(cpp_dec_float_elem_number)
242 {
243 // TODO: this doesn't round!
244 std::copy(f.data.begin(), f.data.begin() + prec_elem, data.begin());
245 }
246
247 template <class F>
248 cpp_dec_float(const F val, typename enable_if<is_floating_point<F> >::type* = 0) :
249 data(),
250 exp (static_cast<ExponentType>(0)),
251 neg (false),
252 fpclass (cpp_dec_float_finite),
253 prec_elem(cpp_dec_float_elem_number)
254 {
255 *this = val;
256 }
257
258 cpp_dec_float(const double mantissa, const ExponentType exponent);
259
260 // Specific special values.
261 static const cpp_dec_float& nan()
262 {
263 static const cpp_dec_float val(cpp_dec_float_NaN);
264 init.do_nothing();
265 return val;
266 }
267
268 static const cpp_dec_float& inf()
269 {
270 static const cpp_dec_float val(cpp_dec_float_inf);
271 init.do_nothing();
272 return val;
273 }
274
275 static const cpp_dec_float& (max)()
276 {
277 init.do_nothing();
278 static cpp_dec_float val_max = std::string("1.0e" + boost::lexical_cast<std::string>(cpp_dec_float_max_exp10)).c_str();
279 return val_max;
280 }
281
282 static const cpp_dec_float& (min)()
283 {
284 init.do_nothing();
285 static cpp_dec_float val_min = std::string("1.0e" + boost::lexical_cast<std::string>(cpp_dec_float_min_exp10)).c_str();
286 return val_min;
287 }
288
289 static const cpp_dec_float& zero()
290 {
291 init.do_nothing();
292 static cpp_dec_float val(static_cast<boost::ulong_long_type>(0u));
293 return val;
294 }
295
296 static const cpp_dec_float& one()
297 {
298 init.do_nothing();
299 static cpp_dec_float val(static_cast<boost::ulong_long_type>(1u));
300 return val;
301 }
302
303 static const cpp_dec_float& two()
304 {
305 init.do_nothing();
306 static cpp_dec_float val(static_cast<boost::ulong_long_type>(2u));
307 return val;
308 }
309
310 static const cpp_dec_float& half()
311 {
312 init.do_nothing();
313 static cpp_dec_float val(0.5L);
314 return val;
315 }
316
317 static const cpp_dec_float& double_min()
318 {
319 init.do_nothing();
320 static cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::min)()));
321 return val;
322 }
323
324 static const cpp_dec_float& double_max()
325 {
326 init.do_nothing();
327 static cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::max)()));
328 return val;
329 }
330
331 static const cpp_dec_float& long_double_min()
332 {
333 init.do_nothing();
334#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
335 static cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::min)()));
336#else
337 static cpp_dec_float val((std::numeric_limits<long double>::min)());
338#endif
339 return val;
340 }
341
342 static const cpp_dec_float& long_double_max()
343 {
344 init.do_nothing();
345#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
346 static cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::max)()));
347#else
348 static cpp_dec_float val((std::numeric_limits<long double>::max)());
349#endif
350 return val;
351 }
352
353 static const cpp_dec_float& long_long_max()
354 {
355 init.do_nothing();
356 static cpp_dec_float val((std::numeric_limits<boost::long_long_type>::max)());
357 return val;
358 }
359
360 static const cpp_dec_float& long_long_min()
361 {
362 init.do_nothing();
363 static cpp_dec_float val((std::numeric_limits<boost::long_long_type>::min)());
364 return val;
365 }
366
367 static const cpp_dec_float& ulong_long_max()
368 {
369 init.do_nothing();
370 static cpp_dec_float val((std::numeric_limits<boost::ulong_long_type>::max)());
371 return val;
372 }
373
374 static const cpp_dec_float& eps()
375 {
376 init.do_nothing();
377 static cpp_dec_float val(1.0, 1 - static_cast<int>(cpp_dec_float_digits10));
378 return val;
379 }
380
381 // Basic operations.
382 cpp_dec_float& operator=(const cpp_dec_float& v) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<array_type&>() = std::declval<const array_type&>()))
383 {
384 data = v.data;
385 exp = v.exp;
386 neg = v.neg;
387 fpclass = v.fpclass;
388 prec_elem = v.prec_elem;
389 return *this;
390 }
391
392 template <unsigned D>
393 cpp_dec_float& operator=(const cpp_dec_float<D>& f)
394 {
395 exp = f.exp;
396 neg = f.neg;
397 fpclass = static_cast<enum_fpclass_type>(static_cast<int>(f.fpclass));
398 unsigned elems = (std::min)(f.prec_elem, cpp_dec_float_elem_number);
399 std::copy(f.data.begin(), f.data.begin() + elems, data.begin());
400 std::fill(data.begin() + elems, data.end(), 0);
401 prec_elem = cpp_dec_float_elem_number;
402 return *this;
403 }
404
405 cpp_dec_float& operator=(boost::long_long_type v)
406 {
407 if(v < 0)
408 {
409 from_unsigned_long_long(u: -v);
410 negate();
411 }
412 else
413 from_unsigned_long_long(u: v);
414 return *this;
415 }
416
417 cpp_dec_float& operator=(boost::ulong_long_type v)
418 {
419 from_unsigned_long_long(u: v);
420 return *this;
421 }
422
423 cpp_dec_float& operator=(long double v);
424
425 cpp_dec_float& operator=(const char* v)
426 {
427 rd_string(s: v);
428 return *this;
429 }
430
431 cpp_dec_float& operator+=(const cpp_dec_float& v);
432 cpp_dec_float& operator-=(const cpp_dec_float& v);
433 cpp_dec_float& operator*=(const cpp_dec_float& v);
434 cpp_dec_float& operator/=(const cpp_dec_float& v);
435
436 cpp_dec_float& add_unsigned_long_long(const boost::ulong_long_type n)
437 {
438 cpp_dec_float t;
439 t.from_unsigned_long_long(n);
440 return *this += t;
441 }
442
443 cpp_dec_float& sub_unsigned_long_long(const boost::ulong_long_type n)
444 {
445 cpp_dec_float t;
446 t.from_unsigned_long_long(n);
447 return *this -= t;
448 }
449
450 cpp_dec_float& mul_unsigned_long_long(const boost::ulong_long_type n);
451 cpp_dec_float& div_unsigned_long_long(const boost::ulong_long_type n);
452
453 // Elementary primitives.
454 cpp_dec_float& calculate_inv ();
455 cpp_dec_float& calculate_sqrt();
456
457 void negate()
458 {
459 if(!iszero())
460 neg = !neg;
461 }
462
463 // Comparison functions
464 bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_NaN); }
465 bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_inf); }
466 bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_finite); }
467
468 bool iszero () const
469 {
470 return ((fpclass == cpp_dec_float_finite) && (data[0u] == 0u));
471 }
472
473 bool isone () const;
474 bool isint () const;
475 bool isneg () const { return neg; }
476
477 // Operators pre-increment and pre-decrement
478 cpp_dec_float& operator++()
479 {
480 return *this += one();
481 }
482
483 cpp_dec_float& operator--()
484 {
485 return *this -= one();
486 }
487
488 std::string str(boost::intmax_t digits, std::ios_base::fmtflags f)const;
489
490 int compare(const cpp_dec_float& v)const;
491
492 template <class V>
493 int compare(const V& v)const
494 {
495 cpp_dec_float<Digits10, ExponentType, Allocator> t;
496 t = v;
497 return compare(t);
498 }
499
500 void swap(cpp_dec_float& v)
501 {
502 data.swap(v.data);
503 std::swap(exp, v.exp);
504 std::swap(neg, v.neg);
505 std::swap(fpclass, v.fpclass);
506 std::swap(prec_elem, v.prec_elem);
507 }
508
509 double extract_double() const;
510 long double extract_long_double() const;
511 boost::long_long_type extract_signed_long_long() const;
512 boost::ulong_long_type extract_unsigned_long_long() const;
513 void extract_parts(double& mantissa, ExponentType& exponent) const;
514 cpp_dec_float extract_integer_part() const;
515
516 void precision(const boost::int32_t prec_digits)
517 {
518 if(prec_digits >= cpp_dec_float_total_digits10)
519 {
520 prec_elem = cpp_dec_float_elem_number;
521 }
522 else
523 {
524 const boost::int32_t elems = static_cast<boost::int32_t>( static_cast<boost::int32_t>( (prec_digits + (cpp_dec_float_elem_digits10 / 2)) / cpp_dec_float_elem_digits10)
525 + static_cast<boost::int32_t>(((prec_digits % cpp_dec_float_elem_digits10) != 0) ? 1 : 0));
526
527 prec_elem = (std::min)(a: cpp_dec_float_elem_number, b: (std::max)(a: elems, b: static_cast<boost::int32_t>(2)));
528 }
529 }
530 static cpp_dec_float pow2(boost::long_long_type i);
531 ExponentType order()const
532 {
533 const bool bo_order_is_zero = ((!(isfinite)()) || (data[0] == static_cast<boost::uint32_t>(0u)));
534 //
535 // Binary search to find the order of the leading term:
536 //
537 ExponentType prefix = 0;
538
539 if(data[0] >= 100000UL)
540 {
541 if(data[0] >= 10000000UL)
542 {
543 if(data[0] >= 100000000UL)
544 {
545 if(data[0] >= 1000000000UL)
546 prefix = 9;
547 else
548 prefix = 8;
549 }
550 else
551 prefix = 7;
552 }
553 else
554 {
555 if(data[0] >= 1000000UL)
556 prefix = 6;
557 else
558 prefix = 5;
559 }
560 }
561 else
562 {
563 if(data[0] >= 1000UL)
564 {
565 if(data[0] >= 10000UL)
566 prefix = 4;
567 else
568 prefix = 3;
569 }
570 else
571 {
572 if(data[0] >= 100)
573 prefix = 2;
574 else if(data[0] >= 10)
575 prefix = 1;
576 }
577 }
578
579 return (bo_order_is_zero ? static_cast<ExponentType>(0) : static_cast<ExponentType>(exp + prefix));
580 }
581
582 template<class Archive>
583 void serialize(Archive & ar, const unsigned int /*version*/)
584 {
585 for(unsigned i = 0; i < data.size(); ++i)
586 ar & data[i];
587 ar & exp;
588 ar & neg;
589 ar & fpclass;
590 ar & prec_elem;
591 }
592
593private:
594 static bool data_elem_is_non_zero_predicate(const boost::uint32_t& d) { return (d != static_cast<boost::uint32_t>(0u)); }
595 static bool data_elem_is_non_nine_predicate(const boost::uint32_t& d) { return (d != static_cast<boost::uint32_t>(cpp_dec_float::cpp_dec_float_elem_mask - 1)); }
596 static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast<char>('0')); }
597
598 void from_unsigned_long_long(const boost::ulong_long_type u);
599
600 int cmp_data(const array_type& vd) const;
601
602
603 static boost::uint32_t mul_loop_uv(boost::uint32_t* const u, const boost::uint32_t* const v, const boost::int32_t p);
604 static boost::uint32_t mul_loop_n (boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p);
605 static boost::uint32_t div_loop_n (boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p);
606
607 bool rd_string(const char* const s);
608
609 template <unsigned D, class ET, class A>
610 friend class cpp_dec_float;
611};
612
613template <unsigned Digits10, class ExponentType, class Allocator>
614typename cpp_dec_float<Digits10, ExponentType, Allocator>::initializer cpp_dec_float<Digits10, ExponentType, Allocator>::init;
615
616template <unsigned Digits10, class ExponentType, class Allocator>
617const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_radix;
618template <unsigned Digits10, class ExponentType, class Allocator>
619const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10_setting;
620template <unsigned Digits10, class ExponentType, class Allocator>
621const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10_limit_lo;
622template <unsigned Digits10, class ExponentType, class Allocator>
623const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10_limit_hi;
624template <unsigned Digits10, class ExponentType, class Allocator>
625const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10;
626template <unsigned Digits10, class ExponentType, class Allocator>
627const ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp;
628template <unsigned Digits10, class ExponentType, class Allocator>
629const ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp;
630template <unsigned Digits10, class ExponentType, class Allocator>
631const ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10;
632template <unsigned Digits10, class ExponentType, class Allocator>
633const ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10;
634template <unsigned Digits10, class ExponentType, class Allocator>
635const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_digits10;
636template <unsigned Digits10, class ExponentType, class Allocator>
637const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_number_request;
638template <unsigned Digits10, class ExponentType, class Allocator>
639const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_number;
640template <unsigned Digits10, class ExponentType, class Allocator>
641const boost::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_mask;
642
643template <unsigned Digits10, class ExponentType, class Allocator>
644cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator+=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v)
645{
646 if((isnan)())
647 {
648 return *this;
649 }
650
651 if((isinf)())
652 {
653 if((v.isinf)() && (isneg() != v.isneg()))
654 {
655 *this = nan();
656 }
657 return *this;
658 }
659
660 if(iszero())
661 {
662 return operator=(v);
663 }
664
665 // Get the offset for the add/sub operation.
666 static const ExponentType max_delta_exp = static_cast<ExponentType>((cpp_dec_float_elem_number - 1) * cpp_dec_float_elem_digits10);
667
668 const ExponentType ofs_exp = static_cast<ExponentType>(exp - v.exp);
669
670 // Check if the operation is out of range, requiring special handling.
671 if(v.iszero() || (ofs_exp > max_delta_exp))
672 {
673 // Result is *this unchanged since v is negligible compared to *this.
674 return *this;
675 }
676 else if(ofs_exp < -max_delta_exp)
677 {
678 // Result is *this = v since *this is negligible compared to v.
679 return operator=(v);
680 }
681
682 // Do the add/sub operation.
683
684 typename array_type::iterator p_u = data.begin();
685 typename array_type::const_iterator p_v = v.data.begin();
686 bool b_copy = false;
687 const boost::int32_t ofs = static_cast<boost::int32_t>(static_cast<boost::int32_t>(ofs_exp) / cpp_dec_float_elem_digits10);
688 array_type n_data;
689
690 if(neg == v.neg)
691 {
692 // Add v to *this, where the data array of either *this or v
693 // might have to be treated with a positive, negative or zero offset.
694 // The result is stored in *this. The data are added one element
695 // at a time, each element with carry.
696 if(ofs >= static_cast<boost::int32_t>(0))
697 {
698 std::copy(v.data.begin(), v.data.end() - static_cast<size_t>(ofs), n_data.begin() + static_cast<size_t>(ofs));
699 std::fill(n_data.begin(), n_data.begin() + static_cast<size_t>(ofs), static_cast<boost::uint32_t>(0u));
700 p_v = n_data.begin();
701 }
702 else
703 {
704 std::copy(data.begin(), data.end() - static_cast<size_t>(-ofs), n_data.begin() + static_cast<size_t>(-ofs));
705 std::fill(n_data.begin(), n_data.begin() + static_cast<size_t>(-ofs), static_cast<boost::uint32_t>(0u));
706 p_u = n_data.begin();
707 b_copy = true;
708 }
709
710 // Addition algorithm
711 boost::uint32_t carry = static_cast<boost::uint32_t>(0u);
712
713 for(boost::int32_t j = static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1)); j >= static_cast<boost::int32_t>(0); j--)
714 {
715 boost::uint32_t t = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(p_u[j] + p_v[j]) + carry);
716 carry = t / static_cast<boost::uint32_t>(cpp_dec_float_elem_mask);
717 p_u[j] = static_cast<boost::uint32_t>(t - static_cast<boost::uint32_t>(carry * static_cast<boost::uint32_t>(cpp_dec_float_elem_mask)));
718 }
719
720 if(b_copy)
721 {
722 data = n_data;
723 exp = v.exp;
724 }
725
726 // There needs to be a carry into the element -1 of the array data
727 if(carry != static_cast<boost::uint32_t>(0u))
728 {
729 std::copy_backward(data.begin(), data.end() - static_cast<std::size_t>(1u), data.end());
730 data[0] = carry;
731 exp += static_cast<ExponentType>(cpp_dec_float_elem_digits10);
732 }
733 }
734 else
735 {
736 // Subtract v from *this, where the data array of either *this or v
737 // might have to be treated with a positive, negative or zero offset.
738 if((ofs > static_cast<boost::int32_t>(0))
739 || ( (ofs == static_cast<boost::int32_t>(0))
740 && (cmp_data(vd: v.data) > static_cast<boost::int32_t>(0)))
741 )
742 {
743 // In this case, |u| > |v| and ofs is positive.
744 // Copy the data of v, shifted down to a lower value
745 // into the data array m_n. Set the operand pointer p_v
746 // to point to the copied, shifted data m_n.
747 std::copy(v.data.begin(), v.data.end() - static_cast<size_t>(ofs), n_data.begin() + static_cast<size_t>(ofs));
748 std::fill(n_data.begin(), n_data.begin() + static_cast<size_t>(ofs), static_cast<boost::uint32_t>(0u));
749 p_v = n_data.begin();
750 }
751 else
752 {
753 if(ofs != static_cast<boost::int32_t>(0))
754 {
755 // In this case, |u| < |v| and ofs is negative.
756 // Shift the data of u down to a lower value.
757 std::copy_backward(data.begin(), data.end() - static_cast<size_t>(-ofs), data.end());
758 std::fill(data.begin(), data.begin() + static_cast<size_t>(-ofs), static_cast<boost::uint32_t>(0u));
759 }
760
761 // Copy the data of v into the data array n_data.
762 // Set the u-pointer p_u to point to m_n and the
763 // operand pointer p_v to point to the shifted
764 // data m_data.
765 n_data = v.data;
766 p_u = n_data.begin();
767 p_v = data.begin();
768 b_copy = true;
769 }
770
771 boost::int32_t j;
772
773 // Subtraction algorithm
774 boost::int32_t borrow = static_cast<boost::int32_t>(0);
775
776 for(j = static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1)); j >= static_cast<boost::int32_t>(0); j--)
777 {
778 boost::int32_t t = static_cast<boost::int32_t>(static_cast<boost::int32_t>( static_cast<boost::int32_t>(p_u[j])
779 - static_cast<boost::int32_t>(p_v[j])) - borrow);
780
781 // Underflow? Borrow?
782 if(t < static_cast<boost::int32_t>(0))
783 {
784 // Yes, underflow and borrow
785 t += static_cast<boost::int32_t>(cpp_dec_float_elem_mask);
786 borrow = static_cast<boost::int32_t>(1);
787 }
788 else
789 {
790 borrow = static_cast<boost::int32_t>(0);
791 }
792
793 p_u[j] = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(t) % static_cast<boost::uint32_t>(cpp_dec_float_elem_mask));
794 }
795
796 if(b_copy)
797 {
798 data = n_data;
799 exp = v.exp;
800 neg = v.neg;
801 }
802
803 // Is it necessary to justify the data?
804 const typename array_type::const_iterator first_nonzero_elem = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate);
805
806 if(first_nonzero_elem != data.begin())
807 {
808 if(first_nonzero_elem == data.end())
809 {
810 // This result of the subtraction is exactly zero.
811 // Reset the sign and the exponent.
812 neg = false;
813 exp = static_cast<ExponentType>(0);
814 }
815 else
816 {
817 // Justify the data
818 const std::size_t sj = static_cast<std::size_t>(std::distance<typename array_type::const_iterator>(data.begin(), first_nonzero_elem));
819
820 std::copy(data.begin() + static_cast<std::size_t>(sj), data.end(), data.begin());
821 std::fill(data.end() - sj, data.end(), static_cast<boost::uint32_t>(0u));
822
823 exp -= static_cast<ExponentType>(sj * static_cast<std::size_t>(cpp_dec_float_elem_digits10));
824 }
825 }
826 }
827
828 // Handle underflow.
829 if(iszero())
830 return (*this = zero());
831
832 // Check for potential overflow.
833 const bool b_result_might_overflow = (exp >= static_cast<ExponentType>(cpp_dec_float_max_exp10));
834
835 // Handle overflow.
836 if(b_result_might_overflow)
837 {
838 const bool b_result_is_neg = neg;
839 neg = false;
840
841 if(compare((cpp_dec_float::max)()) > 0)
842 *this = inf();
843
844 neg = b_result_is_neg;
845 }
846
847 return *this;
848}
849
850template <unsigned Digits10, class ExponentType, class Allocator>
851cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator-=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v)
852{
853 // Use *this - v = -(-*this + v).
854 negate();
855 *this += v;
856 negate();
857 return *this;
858}
859
860template <unsigned Digits10, class ExponentType, class Allocator>
861cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator*=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v)
862{
863 // Evaluate the sign of the result.
864 const bool b_result_is_neg = (neg != v.neg);
865
866 // Artificially set the sign of the result to be positive.
867 neg = false;
868
869 // Handle special cases like zero, inf and NaN.
870 const bool b_u_is_inf = (isinf)();
871 const bool b_v_is_inf = (v.isinf)();
872 const bool b_u_is_zero = iszero();
873 const bool b_v_is_zero = v.iszero();
874
875 if( ((isnan)() || (v.isnan)())
876 || (b_u_is_inf && b_v_is_zero)
877 || (b_v_is_inf && b_u_is_zero)
878 )
879 {
880 *this = nan();
881 return *this;
882 }
883
884 if(b_u_is_inf || b_v_is_inf)
885 {
886 *this = inf();
887 if(b_result_is_neg)
888 negate();
889 return *this;
890 }
891
892 if(b_u_is_zero || b_v_is_zero)
893 {
894 return *this = zero();
895 }
896
897 // Check for potential overflow or underflow.
898 const bool b_result_might_overflow = ((exp + v.exp) >= static_cast<ExponentType>(cpp_dec_float_max_exp10));
899 const bool b_result_might_underflow = ((exp + v.exp) <= static_cast<ExponentType>(cpp_dec_float_min_exp10));
900
901 // Set the exponent of the result.
902 exp += v.exp;
903
904 const boost::int32_t prec_mul = (std::min)(prec_elem, v.prec_elem);
905
906 const boost::uint32_t carry = mul_loop_uv(u: data.data(), v: v.data.data(), p: prec_mul);
907
908 // Handle a potential carry.
909 if(carry != static_cast<boost::uint32_t>(0u))
910 {
911 exp += cpp_dec_float_elem_digits10;
912
913 // Shift the result of the multiplication one element to the right...
914 std::copy_backward(data.begin(),
915 data.begin() + static_cast<std::size_t>(prec_elem - static_cast<boost::int32_t>(1)),
916 data.begin() + static_cast<std::size_t>(prec_elem));
917
918 // ... And insert the carry.
919 data.front() = carry;
920 }
921
922 // Handle overflow.
923 if(b_result_might_overflow && (compare((cpp_dec_float::max)()) > 0))
924 {
925 *this = inf();
926 }
927
928 // Handle underflow.
929 if(b_result_might_underflow && (compare((cpp_dec_float::min)()) < 0))
930 {
931 *this = zero();
932
933 return *this;
934 }
935
936 // Set the sign of the result.
937 neg = b_result_is_neg;
938
939 return *this;
940}
941
942template <unsigned Digits10, class ExponentType, class Allocator>
943cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator/=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v)
944{
945 const bool u_and_v_are_finite_and_identical = ( (isfinite)()
946 && (fpclass == v.fpclass)
947 && (exp == v.exp)
948 && (cmp_data(vd: v.data) == static_cast<boost::int32_t>(0)));
949
950 if(u_and_v_are_finite_and_identical)
951 {
952 if(neg != v.neg)
953 {
954 *this = one();
955 negate();
956 }
957 else
958 *this = one();
959 return *this;
960 }
961 else
962 {
963 if(iszero())
964 {
965 if((v.isnan)() || v.iszero())
966 {
967 return *this = v;
968 }
969 return *this;
970 }
971 cpp_dec_float t(v);
972 t.calculate_inv();
973 return operator*=(v: t);
974 }
975}
976
977template <unsigned Digits10, class ExponentType, class Allocator>
978cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::mul_unsigned_long_long(const boost::ulong_long_type n)
979{
980 // Multiply *this with a constant boost::ulong_long_type.
981
982 // Evaluate the sign of the result.
983 const bool b_neg = neg;
984
985 // Artificially set the sign of the result to be positive.
986 neg = false;
987
988 // Handle special cases like zero, inf and NaN.
989 const bool b_u_is_inf = (isinf)();
990 const bool b_n_is_zero = (n == static_cast<boost::int32_t>(0));
991
992 if((isnan)() || (b_u_is_inf && b_n_is_zero))
993 {
994 return (*this = nan());
995 }
996
997 if(b_u_is_inf)
998 {
999 *this = inf();
1000 if(b_neg)
1001 negate();
1002 return *this;
1003 }
1004
1005 if(iszero() || b_n_is_zero)
1006 {
1007 // Multiplication by zero.
1008 return *this = zero();
1009 }
1010
1011 if(n >= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask))
1012 {
1013 neg = b_neg;
1014 cpp_dec_float t;
1015 t = n;
1016 return operator*=(v: t);
1017 }
1018
1019 if(n == static_cast<boost::ulong_long_type>(1u))
1020 {
1021 neg = b_neg;
1022 return *this;
1023 }
1024
1025 // Set up the multiplication loop.
1026 const boost::uint32_t nn = static_cast<boost::uint32_t>(n);
1027 const boost::uint32_t carry = mul_loop_n(u: data.data(), n: nn, p: prec_elem);
1028
1029 // Handle the carry and adjust the exponent.
1030 if(carry != static_cast<boost::uint32_t>(0u))
1031 {
1032 exp += static_cast<ExponentType>(cpp_dec_float_elem_digits10);
1033
1034 // Shift the result of the multiplication one element to the right.
1035 std::copy_backward(data.begin(),
1036 data.begin() + static_cast<std::size_t>(prec_elem - static_cast<boost::int32_t>(1)),
1037 data.begin() + static_cast<std::size_t>(prec_elem));
1038
1039 data.front() = static_cast<boost::uint32_t>(carry);
1040 }
1041
1042 // Check for potential overflow.
1043 const bool b_result_might_overflow = (exp >= cpp_dec_float_max_exp10);
1044
1045 // Handle overflow.
1046 if(b_result_might_overflow && (compare((cpp_dec_float::max)()) > 0))
1047 {
1048 *this = inf();
1049 }
1050
1051 // Set the sign.
1052 neg = b_neg;
1053
1054 return *this;
1055}
1056
1057template <unsigned Digits10, class ExponentType, class Allocator>
1058cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::div_unsigned_long_long(const boost::ulong_long_type n)
1059{
1060 // Divide *this by a constant boost::ulong_long_type.
1061
1062 // Evaluate the sign of the result.
1063 const bool b_neg = neg;
1064
1065 // Artificially set the sign of the result to be positive.
1066 neg = false;
1067
1068 // Handle special cases like zero, inf and NaN.
1069 if((isnan)())
1070 {
1071 return *this;
1072 }
1073
1074 if((isinf)())
1075 {
1076 *this = inf();
1077 if(b_neg)
1078 negate();
1079 return *this;
1080 }
1081
1082 if(n == static_cast<boost::ulong_long_type>(0u))
1083 {
1084 // Divide by 0.
1085 if(iszero())
1086 {
1087 *this = nan();
1088 return *this;
1089 }
1090 else
1091 {
1092 *this = inf();
1093 if(isneg())
1094 negate();
1095 return *this;
1096 }
1097 }
1098
1099 if(iszero())
1100 {
1101 return *this;
1102 }
1103
1104 if(n >= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask))
1105 {
1106 neg = b_neg;
1107 cpp_dec_float t;
1108 t = n;
1109 return operator/=(v: t);
1110 }
1111
1112 const boost::uint32_t nn = static_cast<boost::uint32_t>(n);
1113
1114 if(nn > static_cast<boost::uint32_t>(1u))
1115 {
1116 // Do the division loop.
1117 const boost::uint32_t prev = div_loop_n(u: data.data(), n: nn, p: prec_elem);
1118
1119 // Determine if one leading zero is in the result data.
1120 if(data[0] == static_cast<boost::uint32_t>(0u))
1121 {
1122 // Adjust the exponent
1123 exp -= static_cast<ExponentType>(cpp_dec_float_elem_digits10);
1124
1125 // Shift result of the division one element to the left.
1126 std::copy(data.begin() + static_cast<std::size_t>(1u),
1127 data.begin() + static_cast<std::size_t>(prec_elem - static_cast<boost::int32_t>(1)),
1128 data.begin());
1129
1130 data[prec_elem - static_cast<boost::int32_t>(1)] = static_cast<boost::uint32_t>(static_cast<boost::uint64_t>(prev * static_cast<boost::uint64_t>(cpp_dec_float_elem_mask)) / nn);
1131 }
1132 }
1133
1134 // Check for potential underflow.
1135 const bool b_result_might_underflow = (exp <= cpp_dec_float_min_exp10);
1136
1137 // Handle underflow.
1138 if(b_result_might_underflow && (compare((cpp_dec_float::min)()) < 0))
1139 return (*this = zero());
1140
1141 // Set the sign of the result.
1142 neg = b_neg;
1143
1144 return *this;
1145}
1146
1147template <unsigned Digits10, class ExponentType, class Allocator>
1148cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::calculate_inv()
1149{
1150 // Compute the inverse of *this.
1151 const bool b_neg = neg;
1152
1153 neg = false;
1154
1155 // Handle special cases like zero, inf and NaN.
1156 if(iszero())
1157 {
1158 *this = inf();
1159 if(b_neg)
1160 negate();
1161 return *this;
1162 }
1163
1164 if((isnan)())
1165 {
1166 return *this;
1167 }
1168
1169 if((isinf)())
1170 {
1171 return *this = zero();
1172 }
1173
1174 if(isone())
1175 {
1176 if(b_neg)
1177 negate();
1178 return *this;
1179 }
1180
1181 // Save the original *this.
1182 cpp_dec_float<Digits10, ExponentType, Allocator> x(*this);
1183
1184 // Generate the initial estimate using division.
1185 // Extract the mantissa and exponent for a "manual"
1186 // computation of the estimate.
1187 double dd;
1188 ExponentType ne;
1189 x.extract_parts(dd, ne);
1190
1191 // Do the inverse estimate using double precision estimates of mantissa and exponent.
1192 operator=(cpp_dec_float<Digits10, ExponentType, Allocator>(1.0 / dd, -ne));
1193
1194 // Compute the inverse of *this. Quadratically convergent Newton-Raphson iteration
1195 // is used. During the iterative steps, the precision of the calculation is limited
1196 // to the minimum required in order to minimize the run-time.
1197
1198 static const boost::int32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3;
1199
1200 for(boost::int32_t digits = double_digits10_minus_a_few; digits <= cpp_dec_float_total_digits10; digits *= static_cast<boost::int32_t>(2))
1201 {
1202 // Adjust precision of the terms.
1203 precision(prec_digits: static_cast<boost::int32_t>((digits + 10) * static_cast<boost::int32_t>(2)));
1204 x.precision(static_cast<boost::int32_t>((digits + 10) * static_cast<boost::int32_t>(2)));
1205
1206 // Next iteration.
1207 cpp_dec_float t(*this);
1208 t *= x;
1209 t -= two();
1210 t.negate();
1211 *this *= t;
1212 }
1213
1214 neg = b_neg;
1215
1216 prec_elem = cpp_dec_float_elem_number;
1217
1218 return *this;
1219}
1220
1221template <unsigned Digits10, class ExponentType, class Allocator>
1222cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::calculate_sqrt()
1223{
1224 // Compute the square root of *this.
1225
1226 if(isneg() || (!(isfinite)()))
1227 {
1228 *this = nan();
1229 return *this;
1230 }
1231
1232 if(iszero() || isone())
1233 {
1234 return *this;
1235 }
1236
1237 // Save the original *this.
1238 cpp_dec_float<Digits10, ExponentType, Allocator> x(*this);
1239
1240 // Generate the initial estimate using division.
1241 // Extract the mantissa and exponent for a "manual"
1242 // computation of the estimate.
1243 double dd;
1244 ExponentType ne;
1245 extract_parts(mantissa&: dd, exponent&: ne);
1246
1247 // Force the exponent to be an even multiple of two.
1248 if((ne % static_cast<ExponentType>(2)) != static_cast<ExponentType>(0))
1249 {
1250 ++ne;
1251 dd /= 10.0;
1252 }
1253
1254 // Setup the iteration.
1255 // Estimate the square root using simple manipulations.
1256 const double sqd = std::sqrt(x: dd);
1257
1258 *this = cpp_dec_float<Digits10, ExponentType, Allocator>(sqd, static_cast<ExponentType>(ne / static_cast<ExponentType>(2)));
1259
1260 // Estimate 1.0 / (2.0 * x0) using simple manipulations.
1261 cpp_dec_float<Digits10, ExponentType, Allocator> vi(0.5 / sqd, static_cast<ExponentType>(-ne / static_cast<ExponentType>(2)));
1262
1263 // Compute the square root of x. Coupled Newton iteration
1264 // as described in "Pi Unleashed" is used. During the
1265 // iterative steps, the precision of the calculation is
1266 // limited to the minimum required in order to minimize
1267 // the run-time.
1268 //
1269 // Book references:
1270 // http://www.jjj.de/pibook/pibook.html
1271 // http://www.amazon.com/exec/obidos/tg/detail/-/3540665722/qid=1035535482/sr=8-7/ref=sr_8_7/104-3357872-6059916?v=glance&n=507846
1272
1273 static const boost::uint32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3;
1274
1275 for(boost::int32_t digits = double_digits10_minus_a_few; digits <= cpp_dec_float_total_digits10; digits *= 2u)
1276 {
1277 // Adjust precision of the terms.
1278 precision(prec_digits: (digits + 10) * 2);
1279 vi.precision((digits + 10) * 2);
1280
1281 // Next iteration of vi
1282 cpp_dec_float t(*this);
1283 t *= vi;
1284 t.negate();
1285 t.mul_unsigned_long_long(2u);
1286 t += one();
1287 t *= vi;
1288 vi += t;
1289
1290 // Next iteration of *this
1291 t = *this;
1292 t *= *this;
1293 t.negate();
1294 t += x;
1295 t *= vi;
1296 *this += t;
1297 }
1298
1299 prec_elem = cpp_dec_float_elem_number;
1300
1301 return *this;
1302}
1303
1304template <unsigned Digits10, class ExponentType, class Allocator>
1305int cpp_dec_float<Digits10, ExponentType, Allocator>::cmp_data(const array_type& vd) const
1306{
1307 // Compare the data of *this with those of v.
1308 // Return +1 for *this > v
1309 // 0 for *this = v
1310 // -1 for *this < v
1311
1312 const std::pair<typename array_type::const_iterator, typename array_type::const_iterator> mismatch_pair = std::mismatch(data.begin(), data.end(), vd.begin());
1313
1314 const bool is_equal = ((mismatch_pair.first == data.end()) && (mismatch_pair.second == vd.end()));
1315
1316 if(is_equal)
1317 {
1318 return 0;
1319 }
1320 else
1321 {
1322 return ((*mismatch_pair.first > *mismatch_pair.second) ? 1 : -1);
1323 }
1324}
1325
1326template <unsigned Digits10, class ExponentType, class Allocator>
1327int cpp_dec_float<Digits10, ExponentType, Allocator>::compare(const cpp_dec_float& v) const
1328{
1329 // Compare v with *this.
1330 // Return +1 for *this > v
1331 // 0 for *this = v
1332 // -1 for *this < v
1333
1334 // Handle all non-finite cases.
1335 if((!(isfinite)()) || (!(v.isfinite)()))
1336 {
1337 // NaN can never equal NaN. Return an implementation-dependent
1338 // signed result. Also note that comparison of NaN with NaN
1339 // using operators greater-than or less-than is undefined.
1340 if((isnan)() || (v.isnan)()) { return ((isnan)() ? 1 : -1); }
1341
1342 if((isinf)() && (v.isinf)())
1343 {
1344 // Both *this and v are infinite. They are equal if they have the same sign.
1345 // Otherwise, *this is less than v if and only if *this is negative.
1346 return ((neg == v.neg) ? 0 : (neg ? -1 : 1));
1347 }
1348
1349 if((isinf)())
1350 {
1351 // *this is infinite, but v is finite.
1352 // So negative infinite *this is less than any finite v.
1353 // Whereas positive infinite *this is greater than any finite v.
1354 return (isneg() ? -1 : 1);
1355 }
1356 else
1357 {
1358 // *this is finite, and v is infinite.
1359 // So any finite *this is greater than negative infinite v.
1360 // Whereas any finite *this is less than positive infinite v.
1361 return (v.neg ? 1 : -1);
1362 }
1363 }
1364
1365 // And now handle all *finite* cases.
1366 if(iszero())
1367 {
1368 // The value of *this is zero and v is either zero or non-zero.
1369 return (v.iszero() ? 0
1370 : (v.neg ? 1 : -1));
1371 }
1372 else if(v.iszero())
1373 {
1374 // The value of v is zero and *this is non-zero.
1375 return (neg ? -1 : 1);
1376 }
1377 else
1378 {
1379 // Both *this and v are non-zero.
1380
1381 if(neg != v.neg)
1382 {
1383 // The signs are different.
1384 return (neg ? -1 : 1);
1385 }
1386 else if(exp != v.exp)
1387 {
1388 // The signs are the same and the exponents are different.
1389 const int val_cexpression = ((exp < v.exp) ? 1 : -1);
1390
1391 return (neg ? val_cexpression : -val_cexpression);
1392 }
1393 else
1394 {
1395 // The signs are the same and the exponents are the same.
1396 // Compare the data.
1397 const int val_cmp_data = cmp_data(vd: v.data);
1398
1399 return ((!neg) ? val_cmp_data : -val_cmp_data);
1400 }
1401 }
1402}
1403
1404template <unsigned Digits10, class ExponentType, class Allocator>
1405bool cpp_dec_float<Digits10, ExponentType, Allocator>::isone() const
1406{
1407 // Check if the value of *this is identically 1 or very close to 1.
1408
1409 const bool not_negative_and_is_finite = ((!neg) && (isfinite)());
1410
1411 if(not_negative_and_is_finite)
1412 {
1413 if((data[0u] == static_cast<boost::uint32_t>(1u)) && (exp == static_cast<ExponentType>(0)))
1414 {
1415 const typename array_type::const_iterator it_non_zero = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate);
1416 return (it_non_zero == data.end());
1417 }
1418 else if((data[0u] == static_cast<boost::uint32_t>(cpp_dec_float_elem_mask - 1)) && (exp == static_cast<ExponentType>(-cpp_dec_float_elem_digits10)))
1419 {
1420 const typename array_type::const_iterator it_non_nine = std::find_if(data.begin(), data.end(), data_elem_is_non_nine_predicate);
1421 return (it_non_nine == data.end());
1422 }
1423 }
1424
1425 return false;
1426}
1427
1428template <unsigned Digits10, class ExponentType, class Allocator>
1429bool cpp_dec_float<Digits10, ExponentType, Allocator>::isint() const
1430{
1431 if(fpclass != cpp_dec_float_finite) { return false; }
1432
1433 if(iszero()) { return true; }
1434
1435 if(exp < static_cast<ExponentType>(0)) { return false; } // |*this| < 1.
1436
1437 const typename array_type::size_type offset_decimal_part = static_cast<typename array_type::size_type>(exp / cpp_dec_float_elem_digits10) + 1u;
1438
1439 if(offset_decimal_part >= static_cast<typename array_type::size_type>(cpp_dec_float_elem_number))
1440 {
1441 // The number is too large to resolve the integer part.
1442 // It considered to be a pure integer.
1443 return true;
1444 }
1445
1446 typename array_type::const_iterator it_non_zero = std::find_if(data.begin() + offset_decimal_part, data.end(), data_elem_is_non_zero_predicate);
1447
1448 return (it_non_zero == data.end());
1449}
1450
1451template <unsigned Digits10, class ExponentType, class Allocator>
1452void cpp_dec_float<Digits10, ExponentType, Allocator>::extract_parts(double& mantissa, ExponentType& exponent) const
1453{
1454 // Extract the approximate parts mantissa and base-10 exponent from the input cpp_dec_float<Digits10, ExponentType, Allocator> value x.
1455
1456 // Extracts the mantissa and exponent.
1457 exponent = exp;
1458
1459 boost::uint32_t p10 = static_cast<boost::uint32_t>(1u);
1460 boost::uint32_t test = data[0u];
1461
1462 for(;;)
1463 {
1464 test /= static_cast<boost::uint32_t>(10u);
1465
1466 if(test == static_cast<boost::uint32_t>(0u))
1467 {
1468 break;
1469 }
1470
1471 p10 *= static_cast<boost::uint32_t>(10u);
1472 ++exponent;
1473 }
1474
1475 // Establish the upper bound of limbs for extracting the double.
1476 const int max_elem_in_double_count = static_cast<int>(static_cast<boost::int32_t>(std::numeric_limits<double>::digits10) / cpp_dec_float_elem_digits10)
1477 + (static_cast<int>(static_cast<boost::int32_t>(std::numeric_limits<double>::digits10) % cpp_dec_float_elem_digits10) != 0 ? 1 : 0)
1478 + 1;
1479
1480 // And make sure this upper bound stays within bounds of the elems.
1481 const std::size_t max_elem_extract_count = static_cast<std::size_t>((std::min)(a: static_cast<boost::int32_t>(max_elem_in_double_count), b: cpp_dec_float_elem_number));
1482
1483 // Extract into the mantissa the first limb, extracted as a double.
1484 mantissa = static_cast<double>(data[0]);
1485 double scale = 1.0;
1486
1487 // Extract the rest of the mantissa piecewise from the limbs.
1488 for(std::size_t i = 1u; i < max_elem_extract_count; i++)
1489 {
1490 scale /= static_cast<double>(cpp_dec_float_elem_mask);
1491 mantissa += (static_cast<double>(data[i]) * scale);
1492 }
1493
1494 mantissa /= static_cast<double>(p10);
1495
1496 if(neg) { mantissa = -mantissa; }
1497}
1498
1499template <unsigned Digits10, class ExponentType, class Allocator>
1500double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_double() const
1501{
1502 // Returns the double conversion of a cpp_dec_float<Digits10, ExponentType, Allocator>.
1503
1504 // Check for non-normal cpp_dec_float<Digits10, ExponentType, Allocator>.
1505 if(!(isfinite)())
1506 {
1507 if((isnan)())
1508 {
1509 return std::numeric_limits<double>::quiet_NaN();
1510 }
1511 else
1512 {
1513 return ((!neg) ? std::numeric_limits<double>::infinity()
1514 : -std::numeric_limits<double>::infinity());
1515 }
1516 }
1517
1518 cpp_dec_float<Digits10, ExponentType, Allocator> xx(*this);
1519 if(xx.isneg())
1520 xx.negate();
1521
1522 // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is zero.
1523 if(iszero() || (xx.compare(double_min()) < 0))
1524 {
1525 return 0.0;
1526 }
1527
1528 // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> exceeds the maximum of double.
1529 if(xx.compare(double_max()) > 0)
1530 {
1531 return ((!neg) ? std::numeric_limits<double>::infinity()
1532 : -std::numeric_limits<double>::infinity());
1533 }
1534
1535 std::stringstream ss;
1536
1537 ss << str(digits: std::numeric_limits<double>::digits10 + (2 + 1), f: std::ios_base::scientific);
1538
1539 double d;
1540 ss >> d;
1541
1542 return d;
1543}
1544
1545template <unsigned Digits10, class ExponentType, class Allocator>
1546long double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_long_double() const
1547{
1548 // Returns the long double conversion of a cpp_dec_float<Digits10, ExponentType, Allocator>.
1549
1550 // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is subnormal.
1551 if(!(isfinite)())
1552 {
1553 if((isnan)())
1554 {
1555 return std::numeric_limits<long double>::quiet_NaN();
1556 }
1557 else
1558 {
1559 return ((!neg) ? std::numeric_limits<long double>::infinity()
1560 : -std::numeric_limits<long double>::infinity());
1561 }
1562 }
1563
1564 cpp_dec_float<Digits10, ExponentType, Allocator> xx(*this);
1565 if(xx.isneg())
1566 xx.negate();
1567
1568 // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is zero.
1569 if(iszero() || (xx.compare(long_double_min()) < 0))
1570 {
1571 return static_cast<long double>(0.0);
1572 }
1573
1574 // Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> exceeds the maximum of double.
1575 if(xx.compare(long_double_max()) > 0)
1576 {
1577 return ((!neg) ? std::numeric_limits<long double>::infinity()
1578 : -std::numeric_limits<long double>::infinity());
1579 }
1580
1581 std::stringstream ss;
1582
1583 ss << str(digits: std::numeric_limits<long double>::digits10 + (2 + 1), f: std::ios_base::scientific);
1584
1585 long double ld;
1586 ss >> ld;
1587
1588 return ld;
1589}
1590
1591template <unsigned Digits10, class ExponentType, class Allocator>
1592boost::long_long_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_long_long() const
1593{
1594 // Extracts a signed long long from *this.
1595 // If (x > maximum of long long) or (x < minimum of long long),
1596 // then the maximum or minimum of long long is returned accordingly.
1597
1598 if(exp < static_cast<ExponentType>(0))
1599 {
1600 return static_cast<boost::long_long_type>(0);
1601 }
1602
1603 const bool b_neg = isneg();
1604
1605 boost::ulong_long_type val;
1606
1607 if((!b_neg) && (compare(long_long_max()) > 0))
1608 {
1609 return (std::numeric_limits<boost::long_long_type>::max)();
1610 }
1611 else if(b_neg && (compare(long_long_min()) < 0))
1612 {
1613 return (std::numeric_limits<boost::long_long_type>::min)();
1614 }
1615 else
1616 {
1617 // Extract the data into an boost::ulong_long_type value.
1618 cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
1619 if(xn.isneg())
1620 xn.negate();
1621
1622 val = static_cast<boost::ulong_long_type>(xn.data[0]);
1623
1624 const boost::int32_t imax = (std::min)(a: static_cast<boost::int32_t>(static_cast<boost::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), b: static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1)));
1625
1626 for(boost::int32_t i = static_cast<boost::int32_t>(1); i <= imax; i++)
1627 {
1628 val *= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask);
1629 val += static_cast<boost::ulong_long_type>(xn.data[i]);
1630 }
1631 }
1632
1633 if (!b_neg)
1634 {
1635 return static_cast<boost::long_long_type>(val);
1636 }
1637 else
1638 {
1639 // This strange expression avoids a hardware trap in the corner case
1640 // that val is the most negative value permitted in boost::long_long_type.
1641 // See https://svn.boost.org/trac/boost/ticket/9740.
1642 //
1643 boost::long_long_type sval = static_cast<boost::long_long_type>(val - 1);
1644 sval = -sval;
1645 --sval;
1646 return sval;
1647 }
1648}
1649
1650template <unsigned Digits10, class ExponentType, class Allocator>
1651boost::ulong_long_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_unsigned_long_long() const
1652{
1653 // Extracts an boost::ulong_long_type from *this.
1654 // If x exceeds the maximum of boost::ulong_long_type,
1655 // then the maximum of boost::ulong_long_type is returned.
1656 // If x is negative, then the boost::ulong_long_type cast of
1657 // the long long extracted value is returned.
1658
1659 if(isneg())
1660 {
1661 return static_cast<boost::ulong_long_type>(extract_signed_long_long());
1662 }
1663
1664 if(exp < static_cast<ExponentType>(0))
1665 {
1666 return static_cast<boost::ulong_long_type>(0u);
1667 }
1668
1669 const cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
1670
1671 boost::ulong_long_type val;
1672
1673 if(xn.compare(ulong_long_max()) > 0)
1674 {
1675 return (std::numeric_limits<boost::ulong_long_type>::max)();
1676 }
1677 else
1678 {
1679 // Extract the data into an boost::ulong_long_type value.
1680 val = static_cast<boost::ulong_long_type>(xn.data[0]);
1681
1682 const boost::int32_t imax = (std::min)(a: static_cast<boost::int32_t>(static_cast<boost::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), b: static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1)));
1683
1684 for(boost::int32_t i = static_cast<boost::int32_t>(1); i <= imax; i++)
1685 {
1686 val *= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask);
1687 val += static_cast<boost::ulong_long_type>(xn.data[i]);
1688 }
1689 }
1690
1691 return val;
1692}
1693
1694template <unsigned Digits10, class ExponentType, class Allocator>
1695cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::extract_integer_part() const
1696{
1697 // Compute the signed integer part of x.
1698
1699 if(!(isfinite)())
1700 {
1701 return *this;
1702 }
1703
1704 if(exp < static_cast<ExponentType>(0))
1705 {
1706 // The absolute value of the number is smaller than 1.
1707 // Thus the integer part is zero.
1708 return zero();
1709 }
1710
1711 // Truncate the digits from the decimal part, including guard digits
1712 // that do not belong to the integer part.
1713
1714 // Make a local copy.
1715 cpp_dec_float<Digits10, ExponentType, Allocator> x = *this;
1716
1717 // Clear out the decimal portion
1718 const size_t first_clear = (static_cast<size_t>(x.exp) / static_cast<size_t>(cpp_dec_float_elem_digits10)) + 1u;
1719 const size_t last_clear = static_cast<size_t>(cpp_dec_float_elem_number);
1720
1721 if(first_clear < last_clear)
1722 std::fill(x.data.begin() + first_clear, x.data.begin() + last_clear, static_cast<boost::uint32_t>(0u));
1723
1724 return x;
1725}
1726
1727template <unsigned Digits10, class ExponentType, class Allocator>
1728std::string cpp_dec_float<Digits10, ExponentType, Allocator>::str(boost::intmax_t number_of_digits, std::ios_base::fmtflags f) const
1729{
1730 if((this->isinf)())
1731 {
1732 if(this->isneg())
1733 return "-inf";
1734 else if(f & std::ios_base::showpos)
1735 return "+inf";
1736 else
1737 return "inf";
1738 }
1739 else if((this->isnan)())
1740 {
1741 return "nan";
1742 }
1743
1744 std::string str;
1745 boost::intmax_t org_digits(number_of_digits);
1746 ExponentType my_exp = order();
1747
1748 if(number_of_digits == 0)
1749 number_of_digits = cpp_dec_float_total_digits10;
1750
1751 if(f & std::ios_base::fixed)
1752 {
1753 number_of_digits += my_exp + 1;
1754 }
1755 else if(f & std::ios_base::scientific)
1756 ++number_of_digits;
1757 // Determine the number of elements needed to provide the requested digits from cpp_dec_float<Digits10, ExponentType, Allocator>.
1758 const std::size_t number_of_elements = (std::min)(a: static_cast<std::size_t>((number_of_digits / static_cast<std::size_t>(cpp_dec_float_elem_digits10)) + 2u),
1759 b: static_cast<std::size_t>(cpp_dec_float_elem_number));
1760
1761 // Extract the remaining digits from cpp_dec_float<Digits10, ExponentType, Allocator> after the decimal point.
1762 str = boost::lexical_cast<std::string>(data[0]);
1763
1764 // Extract all of the digits from cpp_dec_float<Digits10, ExponentType, Allocator>, beginning with the first data element.
1765 for(std::size_t i = static_cast<std::size_t>(1u); i < number_of_elements; i++)
1766 {
1767 std::stringstream ss;
1768
1769 ss << std::setw(static_cast<std::streamsize>(cpp_dec_float_elem_digits10))
1770 << std::setfill(static_cast<char>('0'))
1771 << data[i];
1772
1773 str += ss.str();
1774 }
1775
1776 bool have_leading_zeros = false;
1777
1778 if(number_of_digits == 0)
1779 {
1780 // We only get here if the output format is "fixed" and we just need to
1781 // round the first non-zero digit.
1782 number_of_digits -= my_exp + 1; // reset to original value
1783 str.insert(pos: static_cast<std::string::size_type>(0), n: std::string::size_type(number_of_digits), c: '0');
1784 have_leading_zeros = true;
1785 }
1786
1787 if(number_of_digits < 0)
1788 {
1789 str = "0";
1790 if(isneg())
1791 str.insert(pos: static_cast<std::string::size_type>(0), n: 1, c: '-');
1792 boost::multiprecision::detail::format_float_string(str, 0, number_of_digits - my_exp - 1, f, this->iszero());
1793 return str;
1794 }
1795 else
1796 {
1797 // Cut the output to the size of the precision.
1798 if(str.length() > static_cast<std::string::size_type>(number_of_digits))
1799 {
1800 // Get the digit after the last needed digit for rounding
1801 const boost::uint32_t round = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(str[static_cast<std::string::size_type>(number_of_digits)]) - static_cast<boost::uint32_t>('0'));
1802
1803 bool need_round_up = round >= 5u;
1804
1805 if(round == 5u)
1806 {
1807 const boost::uint32_t ix = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(str[static_cast<std::string::size_type>(number_of_digits - 1)]) - static_cast<boost::uint32_t>('0'));
1808 if((ix & 1u) == 0)
1809 {
1810 // We have an even digit followed by a 5, so we might not actually need to round up
1811 // if all the remaining digits are zero:
1812 if(str.find_first_not_of(c: '0', pos: static_cast<std::string::size_type>(number_of_digits + 1)) == std::string::npos)
1813 {
1814 bool all_zeros = true;
1815 // No none-zero trailing digits in the string, now check whatever parts we didn't convert to the string:
1816 for(std::size_t i = number_of_elements; i < data.size(); i++)
1817 {
1818 if(data[i])
1819 {
1820 all_zeros = false;
1821 break;
1822 }
1823 }
1824 if(all_zeros)
1825 need_round_up = false; // tie break - round to even.
1826 }
1827 }
1828 }
1829
1830 // Truncate the string
1831 str.erase(pos: static_cast<std::string::size_type>(number_of_digits));
1832
1833 if(need_round_up)
1834 {
1835 std::size_t ix = static_cast<std::size_t>(str.length() - 1u);
1836
1837 // Every trailing 9 must be rounded up
1838 while(ix && (static_cast<boost::int32_t>(str.at(n: ix)) - static_cast<boost::int32_t>('0') == static_cast<boost::int32_t>(9)))
1839 {
1840 str.at(n: ix) = static_cast<char>('0');
1841 --ix;
1842 }
1843
1844 if(!ix)
1845 {
1846 // There were nothing but trailing nines.
1847 if(static_cast<boost::int32_t>(static_cast<boost::int32_t>(str.at(n: ix)) - static_cast<boost::int32_t>(0x30)) == static_cast<boost::int32_t>(9))
1848 {
1849 // Increment up to the next order and adjust exponent.
1850 str.at(n: ix) = static_cast<char>('1');
1851 ++my_exp;
1852 }
1853 else
1854 {
1855 // Round up this digit.
1856 ++str.at(n: ix);
1857 }
1858 }
1859 else
1860 {
1861 // Round up the last digit.
1862 ++str[ix];
1863 }
1864 }
1865 }
1866 }
1867
1868 if(have_leading_zeros)
1869 {
1870 // We need to take the zeros back out again, and correct the exponent
1871 // if we rounded up:
1872 if(str[std::string::size_type(number_of_digits - 1)] != '0')
1873 {
1874 ++my_exp;
1875 str.erase(pos: 0, n: std::string::size_type(number_of_digits - 1));
1876 }
1877 else
1878 str.erase(pos: 0, n: std::string::size_type(number_of_digits));
1879 }
1880
1881 if(isneg())
1882 str.insert(pos: static_cast<std::string::size_type>(0), n: 1, c: '-');
1883
1884 boost::multiprecision::detail::format_float_string(str, my_exp, org_digits, f, this->iszero());
1885 return str;
1886}
1887
1888template <unsigned Digits10, class ExponentType, class Allocator>
1889bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* const s)
1890{
1891 try{
1892
1893 std::string str(s);
1894
1895 // TBD: Using several regular expressions may significantly reduce
1896 // the code complexity (and perhaps the run-time) of rd_string().
1897
1898 // Get a possible exponent and remove it.
1899 exp = static_cast<ExponentType>(0);
1900
1901 std::size_t pos;
1902
1903 if( ((pos = str.find(c: 'e')) != std::string::npos)
1904 || ((pos = str.find(c: 'E')) != std::string::npos)
1905 )
1906 {
1907 // Remove the exponent part from the string.
1908 exp = boost::lexical_cast<ExponentType>(static_cast<const char*>(str.c_str() + (pos + 1u)));
1909 str = str.substr(pos: static_cast<std::size_t>(0u), n: pos);
1910 }
1911
1912 // Get a possible +/- sign and remove it.
1913 neg = false;
1914
1915 if(str.size())
1916 {
1917 if(str[0] == '-')
1918 {
1919 neg = true;
1920 str.erase(pos: 0, n: 1);
1921 }
1922 else if(str[0] == '+')
1923 {
1924 str.erase(pos: 0, n: 1);
1925 }
1926 }
1927 //
1928 // Special cases for infinities and NaN's:
1929 //
1930 if((str == "inf") || (str == "INF") || (str == "infinity") || (str == "INFINITY"))
1931 {
1932 if(neg)
1933 {
1934 *this = this->inf();
1935 this->negate();
1936 }
1937 else
1938 *this = this->inf();
1939 return true;
1940 }
1941 if((str.size() >= 3) && ((str.substr(pos: 0, n: 3) == "nan") || (str.substr(pos: 0, n: 3) == "NAN") || (str.substr(pos: 0, n: 3) == "NaN")))
1942 {
1943 *this = this->nan();
1944 return true;
1945 }
1946
1947 // Remove the leading zeros for all input types.
1948 const std::string::iterator fwd_it_leading_zero = std::find_if(first: str.begin(), last: str.end(), pred: char_is_nonzero_predicate);
1949
1950 if(fwd_it_leading_zero != str.begin())
1951 {
1952 if(fwd_it_leading_zero == str.end())
1953 {
1954 // The string contains nothing but leading zeros.
1955 // This string represents zero.
1956 operator=(zero());
1957 return true;
1958 }
1959 else
1960 {
1961 str.erase(first: str.begin(), last: fwd_it_leading_zero);
1962 }
1963 }
1964
1965 // Put the input string into the standard cpp_dec_float<Digits10, ExponentType, Allocator> input form
1966 // aaa.bbbbE+/-n, where aaa has 1...cpp_dec_float_elem_digits10, bbbb has an
1967 // even multiple of cpp_dec_float_elem_digits10 which are possibly zero padded
1968 // on the right-end, and n is a signed 64-bit integer which is an
1969 // even multiple of cpp_dec_float_elem_digits10.
1970
1971 // Find a possible decimal point.
1972 pos = str.find(c: static_cast<char>('.'));
1973
1974 if(pos != std::string::npos)
1975 {
1976 // Remove all trailing insignificant zeros.
1977 const std::string::const_reverse_iterator rit_non_zero = std::find_if(first: str.rbegin(), last: str.rend(), pred: char_is_nonzero_predicate);
1978
1979 if(rit_non_zero != static_cast<std::string::const_reverse_iterator>(str.rbegin()))
1980 {
1981 const std::string::size_type ofs = str.length() - std::distance<std::string::const_reverse_iterator>(first: str.rbegin(), last: rit_non_zero);
1982 str.erase(first: str.begin() + ofs, last: str.end());
1983 }
1984
1985 // Check if the input is identically zero.
1986 if(str == std::string("."))
1987 {
1988 operator=(zero());
1989 return true;
1990 }
1991
1992 // Remove leading significant zeros just after the decimal point
1993 // and adjust the exponent accordingly.
1994 // Note that the while-loop operates only on strings of the form ".000abcd..."
1995 // and peels away the zeros just after the decimal point.
1996 if(str.at(n: static_cast<std::size_t>(0u)) == static_cast<char>('.'))
1997 {
1998 const std::string::iterator it_non_zero = std::find_if(first: str.begin() + 1u, last: str.end(), pred: char_is_nonzero_predicate);
1999
2000 std::size_t delta_exp = static_cast<std::size_t>(0u);
2001
2002 if(str.at(n: static_cast<std::size_t>(1u)) == static_cast<char>('0'))
2003 {
2004 delta_exp = std::distance<std::string::const_iterator>(first: str.begin() + 1u, last: it_non_zero);
2005 }
2006
2007 // Bring one single digit into the mantissa and adjust the exponent accordingly.
2008 str.erase(first: str.begin(), last: it_non_zero);
2009 str.insert(pos: static_cast<std::string::size_type>(1u), s: ".");
2010 exp -= static_cast<ExponentType>(delta_exp + 1u);
2011 }
2012 }
2013 else
2014 {
2015 // Input string has no decimal point: Append decimal point.
2016 str.append(s: ".");
2017 }
2018
2019 // Shift the decimal point such that the exponent is an even multiple of cpp_dec_float_elem_digits10.
2020 std::size_t n_shift = static_cast<std::size_t>(0u);
2021 const std::size_t n_exp_rem = static_cast<std::size_t>(exp % static_cast<ExponentType>(cpp_dec_float_elem_digits10));
2022
2023 if((exp % static_cast<ExponentType>(cpp_dec_float_elem_digits10)) != static_cast<ExponentType>(0))
2024 {
2025 n_shift = ((exp < static_cast<ExponentType>(0))
2026 ? static_cast<std::size_t>(n_exp_rem + static_cast<std::size_t>(cpp_dec_float_elem_digits10))
2027 : static_cast<std::size_t>(n_exp_rem));
2028 }
2029
2030 // Make sure that there are enough digits for the decimal point shift.
2031 pos = str.find(c: static_cast<char>('.'));
2032
2033 std::size_t pos_plus_one = static_cast<std::size_t>(pos + 1u);
2034
2035 if((str.length() - pos_plus_one) < n_shift)
2036 {
2037 const std::size_t sz = static_cast<std::size_t>(n_shift - (str.length() - pos_plus_one));
2038
2039 str.append(str: std::string(sz, static_cast<char>('0')));
2040 }
2041
2042 // Do the decimal point shift.
2043 if(n_shift != static_cast<std::size_t>(0u))
2044 {
2045 str.insert(pos: static_cast<std::string::size_type>(pos_plus_one + n_shift), s: ".");
2046
2047 str.erase(pos: pos, n: static_cast<std::string::size_type>(1u));
2048
2049 exp -= static_cast<ExponentType>(n_shift);
2050 }
2051
2052 // Cut the size of the mantissa to <= cpp_dec_float_elem_digits10.
2053 pos = str.find(c: static_cast<char>('.'));
2054 pos_plus_one = static_cast<std::size_t>(pos + 1u);
2055
2056 if(pos > static_cast<std::size_t>(cpp_dec_float_elem_digits10))
2057 {
2058 const boost::int32_t n_pos = static_cast<boost::int32_t>(pos);
2059 const boost::int32_t n_rem_is_zero = ((static_cast<boost::int32_t>(n_pos % cpp_dec_float_elem_digits10) == static_cast<boost::int32_t>(0)) ? static_cast<boost::int32_t>(1) : static_cast<boost::int32_t>(0));
2060 const boost::int32_t n = static_cast<boost::int32_t>(static_cast<boost::int32_t>(n_pos / cpp_dec_float_elem_digits10) - n_rem_is_zero);
2061
2062 str.insert(pos: static_cast<std::size_t>(static_cast<boost::int32_t>(n_pos - static_cast<boost::int32_t>(n * cpp_dec_float_elem_digits10))), s: ".");
2063
2064 str.erase(pos: pos_plus_one, n: static_cast<std::size_t>(1u));
2065
2066 exp += static_cast<ExponentType>(static_cast<ExponentType>(n) * static_cast<ExponentType>(cpp_dec_float_elem_digits10));
2067 }
2068
2069 // Pad the decimal part such that its value is an even
2070 // multiple of cpp_dec_float_elem_digits10.
2071 pos = str.find(c: static_cast<char>('.'));
2072 pos_plus_one = static_cast<std::size_t>(pos + 1u);
2073
2074 const boost::int32_t n_dec = static_cast<boost::int32_t>(static_cast<boost::int32_t>(str.length() - 1u) - static_cast<boost::int32_t>(pos));
2075 const boost::int32_t n_rem = static_cast<boost::int32_t>(n_dec % cpp_dec_float_elem_digits10);
2076
2077 boost::int32_t n_cnt = ((n_rem != static_cast<boost::int32_t>(0))
2078 ? static_cast<boost::int32_t>(cpp_dec_float_elem_digits10 - n_rem)
2079 : static_cast<boost::int32_t>(0));
2080
2081 if(n_cnt != static_cast<boost::int32_t>(0))
2082 {
2083 str.append(n: static_cast<std::size_t>(n_cnt), c: static_cast<char>('0'));
2084 }
2085
2086 // Truncate decimal part if it is too long.
2087 const std::size_t max_dec = static_cast<std::size_t>((cpp_dec_float_elem_number - 1) * cpp_dec_float_elem_digits10);
2088
2089 if(static_cast<std::size_t>(str.length() - pos) > max_dec)
2090 {
2091 str = str.substr(pos: static_cast<std::size_t>(0u),
2092 n: static_cast<std::size_t>(pos_plus_one + max_dec));
2093 }
2094
2095 // Now the input string has the standard cpp_dec_float<Digits10, ExponentType, Allocator> input form.
2096 // (See the comment above.)
2097
2098 // Set all the data elements to 0.
2099 std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u));
2100
2101 // Extract the data.
2102
2103 // First get the digits to the left of the decimal point...
2104 data[0u] = boost::lexical_cast<boost::uint32_t>(arg: str.substr(pos: static_cast<std::size_t>(0u), n: pos));
2105
2106 // ...then get the remaining digits to the right of the decimal point.
2107 const std::string::size_type i_end = ((str.length() - pos_plus_one) / static_cast<std::string::size_type>(cpp_dec_float_elem_digits10));
2108
2109 for(std::string::size_type i = static_cast<std::string::size_type>(0u); i < i_end; i++)
2110 {
2111 const std::string::const_iterator it = str.begin()
2112 + pos_plus_one
2113 + (i * static_cast<std::string::size_type>(cpp_dec_float_elem_digits10));
2114
2115 data[i + 1u] = boost::lexical_cast<boost::uint32_t>(arg: std::string(it, it + static_cast<std::string::size_type>(cpp_dec_float_elem_digits10)));
2116 }
2117
2118 // Check for overflow...
2119 if(exp > cpp_dec_float_max_exp10)
2120 {
2121 const bool b_result_is_neg = neg;
2122
2123 *this = inf();
2124 if(b_result_is_neg)
2125 negate();
2126 }
2127
2128 // ...and check for underflow.
2129 if(exp <= cpp_dec_float_min_exp10)
2130 {
2131 if(exp == cpp_dec_float_min_exp10)
2132 {
2133 // Check for identity with the minimum value.
2134 cpp_dec_float<Digits10, ExponentType, Allocator> test = *this;
2135
2136 test.exp = static_cast<ExponentType>(0);
2137
2138 if(test.isone())
2139 {
2140 *this = zero();
2141 }
2142 }
2143 else
2144 {
2145 *this = zero();
2146 }
2147 }
2148
2149 }
2150 catch(const bad_lexical_cast&)
2151 {
2152 // Rethrow with better error message:
2153 std::string msg = "Unable to parse the string \"";
2154 msg += s;
2155 msg += "\" as a floating point value.";
2156 throw std::runtime_error(msg);
2157 }
2158
2159 return true;
2160}
2161
2162template <unsigned Digits10, class ExponentType, class Allocator>
2163cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float(const double mantissa, const ExponentType exponent)
2164 : data (),
2165 exp (static_cast<ExponentType>(0)),
2166 neg (false),
2167 fpclass (cpp_dec_float_finite),
2168 prec_elem(cpp_dec_float_elem_number)
2169{
2170 // Create *this cpp_dec_float<Digits10, ExponentType, Allocator> from a given mantissa and exponent.
2171 // Note: This constructor does not maintain the full precision of double.
2172
2173 const bool mantissa_is_iszero = (::fabs(x: mantissa) < ((std::numeric_limits<double>::min)() * (1.0 + std::numeric_limits<double>::epsilon())));
2174
2175 if(mantissa_is_iszero)
2176 {
2177 std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u));
2178 return;
2179 }
2180
2181 const bool b_neg = (mantissa < 0.0);
2182
2183 double d = ((!b_neg) ? mantissa : -mantissa);
2184 ExponentType e = exponent;
2185
2186 while(d > 10.0) { d /= 10.0; ++e; }
2187 while(d < 1.0) { d *= 10.0; --e; }
2188
2189 boost::int32_t shift = static_cast<boost::int32_t>(e % static_cast<boost::int32_t>(cpp_dec_float_elem_digits10));
2190
2191 while(static_cast<boost::int32_t>(shift-- % cpp_dec_float_elem_digits10) != static_cast<boost::int32_t>(0))
2192 {
2193 d *= 10.0;
2194 --e;
2195 }
2196
2197 exp = e;
2198 neg = b_neg;
2199
2200 std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u));
2201
2202 static const boost::int32_t digit_ratio = static_cast<boost::int32_t>(static_cast<boost::int32_t>(std::numeric_limits<double>::digits10) / static_cast<boost::int32_t>(cpp_dec_float_elem_digits10));
2203 static const boost::int32_t digit_loops = static_cast<boost::int32_t>(digit_ratio + static_cast<boost::int32_t>(2));
2204
2205 for(boost::int32_t i = static_cast<boost::int32_t>(0); i < digit_loops; i++)
2206 {
2207 boost::uint32_t n = static_cast<boost::uint32_t>(static_cast<boost::uint64_t>(d));
2208 data[i] = static_cast<boost::uint32_t>(n);
2209 d -= static_cast<double>(n);
2210 d *= static_cast<double>(cpp_dec_float_elem_mask);
2211 }
2212}
2213
2214template <unsigned Digits10, class ExponentType, class Allocator>
2215cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator= (long double a)
2216{
2217 // Christopher Kormanyos's original code used a cast to boost::long_long_type here, but that fails
2218 // when long double has more digits than a boost::long_long_type.
2219 using std::frexp;
2220 using std::ldexp;
2221 using std::floor;
2222
2223 if(a == 0)
2224 return *this = zero();
2225
2226 if(a == 1)
2227 return *this = one();
2228
2229 if((boost::math::isinf)(x: a))
2230 return *this = inf();
2231
2232 if((boost::math::isnan)(x: a))
2233 return *this = nan();
2234
2235 int e;
2236 long double f, term;
2237 *this = zero();
2238
2239 f = frexp(a, &e);
2240 // See https://svn.boost.org/trac/boost/ticket/10924 for an example of why this may go wrong:
2241 BOOST_ASSERT((boost::math::isfinite)(f));
2242
2243 static const int shift = std::numeric_limits<int>::digits - 1;
2244
2245 while(f)
2246 {
2247 // extract int sized bits from f:
2248 f = ldexp(f, shift);
2249 BOOST_ASSERT((boost::math::isfinite)(f));
2250 term = floor(f);
2251 e -= shift;
2252 *this *= pow2(i: shift);
2253 if(term > 0)
2254 add_unsigned_long_long(n: static_cast<unsigned>(term));
2255 else
2256 sub_unsigned_long_long(n: static_cast<unsigned>(-term));
2257 f -= term;
2258 }
2259
2260 if(e != 0)
2261 *this *= pow2(i: e);
2262
2263 return *this;
2264}
2265
2266template <unsigned Digits10, class ExponentType, class Allocator>
2267void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(const boost::ulong_long_type u)
2268{
2269 std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u));
2270
2271 exp = static_cast<ExponentType>(0);
2272 neg = false;
2273 fpclass = cpp_dec_float_finite;
2274 prec_elem = cpp_dec_float_elem_number;
2275
2276 std::size_t i =static_cast<std::size_t>(0u);
2277
2278 boost::ulong_long_type uu = u;
2279
2280 boost::uint32_t temp[(std::numeric_limits<boost::ulong_long_type>::digits10 / static_cast<int>(cpp_dec_float_elem_digits10)) + 3] = { static_cast<boost::uint32_t>(0u) };
2281
2282 while(uu != static_cast<boost::ulong_long_type>(0u))
2283 {
2284 temp[i] = static_cast<boost::uint32_t>(uu % static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask));
2285 uu = static_cast<boost::ulong_long_type>(uu / static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask));
2286 ++i;
2287 }
2288
2289 if(i > static_cast<std::size_t>(1u))
2290 {
2291 exp += static_cast<ExponentType>((i - 1u) * static_cast<std::size_t>(cpp_dec_float_elem_digits10));
2292 }
2293
2294 std::reverse(first: temp, last: temp + i);
2295 std::copy(temp, temp + (std::min)(a: i, b: static_cast<std::size_t>(cpp_dec_float_elem_number)), data.begin());
2296}
2297
2298template <unsigned Digits10, class ExponentType, class Allocator>
2299boost::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::mul_loop_uv(boost::uint32_t* const u, const boost::uint32_t* const v, const boost::int32_t p)
2300{
2301 //
2302 // There is a limit on how many limbs this algorithm can handle without dropping digits
2303 // due to overflow in the carry, it is:
2304 //
2305 // FLOOR( (2^64 - 1) / (10^8 * 10^8) ) == 1844
2306 //
2307 BOOST_STATIC_ASSERT_MSG(cpp_dec_float_elem_number < 1800, "Too many limbs in the data type for the multiplication algorithm - unsupported precision in cpp_dec_float.");
2308
2309 boost::uint64_t carry = static_cast<boost::uint64_t>(0u);
2310
2311 for(boost::int32_t j = static_cast<boost::int32_t>(p - 1u); j >= static_cast<boost::int32_t>(0); j--)
2312 {
2313 boost::uint64_t sum = carry;
2314
2315 for(boost::int32_t i = j; i >= static_cast<boost::int32_t>(0); i--)
2316 {
2317 sum += static_cast<boost::uint64_t>(u[j - i] * static_cast<boost::uint64_t>(v[i]));
2318 }
2319
2320 u[j] = static_cast<boost::uint32_t>(sum % static_cast<boost::uint32_t>(cpp_dec_float_elem_mask));
2321 carry = static_cast<boost::uint64_t>(sum / static_cast<boost::uint32_t>(cpp_dec_float_elem_mask));
2322 }
2323
2324 return static_cast<boost::uint32_t>(carry);
2325}
2326
2327template <unsigned Digits10, class ExponentType, class Allocator>
2328boost::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::mul_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p)
2329{
2330 boost::uint64_t carry = static_cast<boost::uint64_t>(0u);
2331
2332 // Multiplication loop.
2333 for(boost::int32_t j = p - 1; j >= static_cast<boost::int32_t>(0); j--)
2334 {
2335 const boost::uint64_t t = static_cast<boost::uint64_t>(carry + static_cast<boost::uint64_t>(u[j] * static_cast<boost::uint64_t>(n)));
2336 carry = static_cast<boost::uint64_t>(t / static_cast<boost::uint32_t>(cpp_dec_float_elem_mask));
2337 u[j] = static_cast<boost::uint32_t>(t - static_cast<boost::uint64_t>(static_cast<boost::uint32_t>(cpp_dec_float_elem_mask) * static_cast<boost::uint64_t>(carry)));
2338 }
2339
2340 return static_cast<boost::uint32_t>(carry);
2341}
2342
2343template <unsigned Digits10, class ExponentType, class Allocator>
2344boost::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::div_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p)
2345{
2346 boost::uint64_t prev = static_cast<boost::uint64_t>(0u);
2347
2348 for(boost::int32_t j = static_cast<boost::int32_t>(0); j < p; j++)
2349 {
2350 const boost::uint64_t t = static_cast<boost::uint64_t>(u[j] + static_cast<boost::uint64_t>(prev * static_cast<boost::uint32_t>(cpp_dec_float_elem_mask)));
2351 u[j] = static_cast<boost::uint32_t>(t / n);
2352 prev = static_cast<boost::uint64_t>(t - static_cast<boost::uint64_t>(n * static_cast<boost::uint64_t>(u[j])));
2353 }
2354
2355 return static_cast<boost::uint32_t>(prev);
2356}
2357
2358template <unsigned Digits10, class ExponentType, class Allocator>
2359cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(const boost::long_long_type p)
2360{
2361 // Create a static const table of p^2 for -128 < p < +128.
2362 // Note: The size of this table must be odd-numbered and
2363 // symmetric about 0.
2364 init.do_nothing();
2365 static const boost::array<cpp_dec_float<Digits10, ExponentType, Allocator>, 255u> p2_data =
2366 {{
2367 cpp_dec_float("5.877471754111437539843682686111228389093327783860437607543758531392086297273635864257812500000000000e-39"),
2368 cpp_dec_float("1.175494350822287507968736537222245677818665556772087521508751706278417259454727172851562500000000000e-38"),
2369 cpp_dec_float("2.350988701644575015937473074444491355637331113544175043017503412556834518909454345703125000000000000e-38"),
2370 cpp_dec_float("4.701977403289150031874946148888982711274662227088350086035006825113669037818908691406250000000000000e-38"),
2371 cpp_dec_float("9.403954806578300063749892297777965422549324454176700172070013650227338075637817382812500000000000000e-38"),
2372 cpp_dec_float("1.880790961315660012749978459555593084509864890835340034414002730045467615127563476562500000000000000e-37"),
2373 cpp_dec_float("3.761581922631320025499956919111186169019729781670680068828005460090935230255126953125000000000000000e-37"),
2374 cpp_dec_float("7.523163845262640050999913838222372338039459563341360137656010920181870460510253906250000000000000000e-37"),
2375 cpp_dec_float("1.504632769052528010199982767644474467607891912668272027531202184036374092102050781250000000000000000e-36"),
2376 cpp_dec_float("3.009265538105056020399965535288948935215783825336544055062404368072748184204101562500000000000000000e-36"),
2377 cpp_dec_float("6.018531076210112040799931070577897870431567650673088110124808736145496368408203125000000000000000000e-36"),
2378 cpp_dec_float("1.203706215242022408159986214115579574086313530134617622024961747229099273681640625000000000000000000e-35"),
2379 cpp_dec_float("2.407412430484044816319972428231159148172627060269235244049923494458198547363281250000000000000000000e-35"),
2380 cpp_dec_float("4.814824860968089632639944856462318296345254120538470488099846988916397094726562500000000000000000000e-35"),
2381 cpp_dec_float("9.629649721936179265279889712924636592690508241076940976199693977832794189453125000000000000000000000e-35"),
2382 cpp_dec_float("1.925929944387235853055977942584927318538101648215388195239938795566558837890625000000000000000000000e-34"),
2383 cpp_dec_float("3.851859888774471706111955885169854637076203296430776390479877591133117675781250000000000000000000000e-34"),
2384 cpp_dec_float("7.703719777548943412223911770339709274152406592861552780959755182266235351562500000000000000000000000e-34"),
2385 cpp_dec_float("1.540743955509788682444782354067941854830481318572310556191951036453247070312500000000000000000000000e-33"),
2386 cpp_dec_float("3.081487911019577364889564708135883709660962637144621112383902072906494140625000000000000000000000000e-33"),
2387 cpp_dec_float("6.162975822039154729779129416271767419321925274289242224767804145812988281250000000000000000000000000e-33"),
2388 cpp_dec_float("1.232595164407830945955825883254353483864385054857848444953560829162597656250000000000000000000000000e-32"),
2389 cpp_dec_float("2.465190328815661891911651766508706967728770109715696889907121658325195312500000000000000000000000000e-32"),
2390 cpp_dec_float("4.930380657631323783823303533017413935457540219431393779814243316650390625000000000000000000000000000e-32"),
2391 cpp_dec_float("9.860761315262647567646607066034827870915080438862787559628486633300781250000000000000000000000000000e-32"),
2392 cpp_dec_float("1.972152263052529513529321413206965574183016087772557511925697326660156250000000000000000000000000000e-31"),
2393 cpp_dec_float("3.944304526105059027058642826413931148366032175545115023851394653320312500000000000000000000000000000e-31"),
2394 cpp_dec_float("7.888609052210118054117285652827862296732064351090230047702789306640625000000000000000000000000000000e-31"),
2395 cpp_dec_float("1.577721810442023610823457130565572459346412870218046009540557861328125000000000000000000000000000000e-30"),
2396 cpp_dec_float("3.155443620884047221646914261131144918692825740436092019081115722656250000000000000000000000000000000e-30"),
2397 cpp_dec_float("6.310887241768094443293828522262289837385651480872184038162231445312500000000000000000000000000000000e-30"),
2398 cpp_dec_float("1.262177448353618888658765704452457967477130296174436807632446289062500000000000000000000000000000000e-29"),
2399 cpp_dec_float("2.524354896707237777317531408904915934954260592348873615264892578125000000000000000000000000000000000e-29"),
2400 cpp_dec_float("5.048709793414475554635062817809831869908521184697747230529785156250000000000000000000000000000000000e-29"),
2401 cpp_dec_float("1.009741958682895110927012563561966373981704236939549446105957031250000000000000000000000000000000000e-28"),
2402 cpp_dec_float("2.019483917365790221854025127123932747963408473879098892211914062500000000000000000000000000000000000e-28"),
2403 cpp_dec_float("4.038967834731580443708050254247865495926816947758197784423828125000000000000000000000000000000000000e-28"),
2404 cpp_dec_float("8.077935669463160887416100508495730991853633895516395568847656250000000000000000000000000000000000000e-28"),
2405 cpp_dec_float("1.615587133892632177483220101699146198370726779103279113769531250000000000000000000000000000000000000e-27"),
2406 cpp_dec_float("3.231174267785264354966440203398292396741453558206558227539062500000000000000000000000000000000000000e-27"),
2407 cpp_dec_float("6.462348535570528709932880406796584793482907116413116455078125000000000000000000000000000000000000000e-27"),
2408 cpp_dec_float("1.292469707114105741986576081359316958696581423282623291015625000000000000000000000000000000000000000e-26"),
2409 cpp_dec_float("2.584939414228211483973152162718633917393162846565246582031250000000000000000000000000000000000000000e-26"),
2410 cpp_dec_float("5.169878828456422967946304325437267834786325693130493164062500000000000000000000000000000000000000000e-26"),
2411 cpp_dec_float("1.033975765691284593589260865087453566957265138626098632812500000000000000000000000000000000000000000e-25"),
2412 cpp_dec_float("2.067951531382569187178521730174907133914530277252197265625000000000000000000000000000000000000000000e-25"),
2413 cpp_dec_float("4.135903062765138374357043460349814267829060554504394531250000000000000000000000000000000000000000000e-25"),
2414 cpp_dec_float("8.271806125530276748714086920699628535658121109008789062500000000000000000000000000000000000000000000e-25"),
2415 cpp_dec_float("1.654361225106055349742817384139925707131624221801757812500000000000000000000000000000000000000000000e-24"),
2416 cpp_dec_float("3.308722450212110699485634768279851414263248443603515625000000000000000000000000000000000000000000000e-24"),
2417 cpp_dec_float("6.617444900424221398971269536559702828526496887207031250000000000000000000000000000000000000000000000e-24"),
2418 cpp_dec_float("1.323488980084844279794253907311940565705299377441406250000000000000000000000000000000000000000000000e-23"),
2419 cpp_dec_float("2.646977960169688559588507814623881131410598754882812500000000000000000000000000000000000000000000000e-23"),
2420 cpp_dec_float("5.293955920339377119177015629247762262821197509765625000000000000000000000000000000000000000000000000e-23"),
2421 cpp_dec_float("1.058791184067875423835403125849552452564239501953125000000000000000000000000000000000000000000000000e-22"),
2422 cpp_dec_float("2.117582368135750847670806251699104905128479003906250000000000000000000000000000000000000000000000000e-22"),
2423 cpp_dec_float("4.235164736271501695341612503398209810256958007812500000000000000000000000000000000000000000000000000e-22"),
2424 cpp_dec_float("8.470329472543003390683225006796419620513916015625000000000000000000000000000000000000000000000000000e-22"),
2425 cpp_dec_float("1.694065894508600678136645001359283924102783203125000000000000000000000000000000000000000000000000000e-21"),
2426 cpp_dec_float("3.388131789017201356273290002718567848205566406250000000000000000000000000000000000000000000000000000e-21"),
2427 cpp_dec_float("6.776263578034402712546580005437135696411132812500000000000000000000000000000000000000000000000000000e-21"),
2428 cpp_dec_float("1.355252715606880542509316001087427139282226562500000000000000000000000000000000000000000000000000000e-20"),
2429 cpp_dec_float("2.710505431213761085018632002174854278564453125000000000000000000000000000000000000000000000000000000e-20"),
2430 cpp_dec_float("5.421010862427522170037264004349708557128906250000000000000000000000000000000000000000000000000000000e-20"),
2431 cpp_dec_float("1.084202172485504434007452800869941711425781250000000000000000000000000000000000000000000000000000000e-19"),
2432 cpp_dec_float("2.168404344971008868014905601739883422851562500000000000000000000000000000000000000000000000000000000e-19"),
2433 cpp_dec_float("4.336808689942017736029811203479766845703125000000000000000000000000000000000000000000000000000000000e-19"),
2434 cpp_dec_float("8.673617379884035472059622406959533691406250000000000000000000000000000000000000000000000000000000000e-19"),
2435 cpp_dec_float("1.734723475976807094411924481391906738281250000000000000000000000000000000000000000000000000000000000e-18"),
2436 cpp_dec_float("3.469446951953614188823848962783813476562500000000000000000000000000000000000000000000000000000000000e-18"),
2437 cpp_dec_float("6.938893903907228377647697925567626953125000000000000000000000000000000000000000000000000000000000000e-18"),
2438 cpp_dec_float("1.387778780781445675529539585113525390625000000000000000000000000000000000000000000000000000000000000e-17"),
2439 cpp_dec_float("2.775557561562891351059079170227050781250000000000000000000000000000000000000000000000000000000000000e-17"),
2440 cpp_dec_float("5.551115123125782702118158340454101562500000000000000000000000000000000000000000000000000000000000000e-17"),
2441 cpp_dec_float("1.110223024625156540423631668090820312500000000000000000000000000000000000000000000000000000000000000e-16"),
2442 cpp_dec_float("2.220446049250313080847263336181640625000000000000000000000000000000000000000000000000000000000000000e-16"),
2443 cpp_dec_float("4.440892098500626161694526672363281250000000000000000000000000000000000000000000000000000000000000000e-16"),
2444 cpp_dec_float("8.881784197001252323389053344726562500000000000000000000000000000000000000000000000000000000000000000e-16"),
2445 cpp_dec_float("1.776356839400250464677810668945312500000000000000000000000000000000000000000000000000000000000000000e-15"),
2446 cpp_dec_float("3.552713678800500929355621337890625000000000000000000000000000000000000000000000000000000000000000000e-15"),
2447 cpp_dec_float("7.105427357601001858711242675781250000000000000000000000000000000000000000000000000000000000000000000e-15"),
2448 cpp_dec_float("1.421085471520200371742248535156250000000000000000000000000000000000000000000000000000000000000000000e-14"),
2449 cpp_dec_float("2.842170943040400743484497070312500000000000000000000000000000000000000000000000000000000000000000000e-14"),
2450 cpp_dec_float("5.684341886080801486968994140625000000000000000000000000000000000000000000000000000000000000000000000e-14"),
2451 cpp_dec_float("1.136868377216160297393798828125000000000000000000000000000000000000000000000000000000000000000000000e-13"),
2452 cpp_dec_float("2.273736754432320594787597656250000000000000000000000000000000000000000000000000000000000000000000000e-13"),
2453 cpp_dec_float("4.547473508864641189575195312500000000000000000000000000000000000000000000000000000000000000000000000e-13"),
2454 cpp_dec_float("9.094947017729282379150390625000000000000000000000000000000000000000000000000000000000000000000000000e-13"),
2455 cpp_dec_float("1.818989403545856475830078125000000000000000000000000000000000000000000000000000000000000000000000000e-12"),
2456 cpp_dec_float("3.637978807091712951660156250000000000000000000000000000000000000000000000000000000000000000000000000e-12"),
2457 cpp_dec_float("7.275957614183425903320312500000000000000000000000000000000000000000000000000000000000000000000000000e-12"),
2458 cpp_dec_float("1.455191522836685180664062500000000000000000000000000000000000000000000000000000000000000000000000000e-11"),
2459 cpp_dec_float("2.910383045673370361328125000000000000000000000000000000000000000000000000000000000000000000000000000e-11"),
2460 cpp_dec_float("5.820766091346740722656250000000000000000000000000000000000000000000000000000000000000000000000000000e-11"),
2461 cpp_dec_float("1.164153218269348144531250000000000000000000000000000000000000000000000000000000000000000000000000000e-10"),
2462 cpp_dec_float("2.328306436538696289062500000000000000000000000000000000000000000000000000000000000000000000000000000e-10"),
2463 cpp_dec_float("4.656612873077392578125000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"),
2464 cpp_dec_float("9.313225746154785156250000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"),
2465 cpp_dec_float("1.862645149230957031250000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"),
2466 cpp_dec_float("3.725290298461914062500000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"),
2467 cpp_dec_float("7.450580596923828125000000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"),
2468 cpp_dec_float("1.490116119384765625000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"),
2469 cpp_dec_float("2.980232238769531250000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"),
2470 cpp_dec_float("5.960464477539062500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"),
2471 cpp_dec_float("1.192092895507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"),
2472 cpp_dec_float("2.384185791015625000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"),
2473 cpp_dec_float("4.768371582031250000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"),
2474 cpp_dec_float("9.536743164062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"),
2475 cpp_dec_float("1.907348632812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"),
2476 cpp_dec_float("3.814697265625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"),
2477 cpp_dec_float("7.629394531250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"),
2478 cpp_dec_float("0.000015258789062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2479 cpp_dec_float("0.000030517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2480 cpp_dec_float("0.000061035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2481 cpp_dec_float("0.000122070312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2482 cpp_dec_float("0.000244140625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2483 cpp_dec_float("0.000488281250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2484 cpp_dec_float("0.000976562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2485 cpp_dec_float("0.001953125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2486 cpp_dec_float("0.003906250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2487 cpp_dec_float("0.007812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2488 cpp_dec_float("0.01562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2489 cpp_dec_float("0.03125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2490 cpp_dec_float("0.06250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
2491 cpp_dec_float("0.125"),
2492 cpp_dec_float("0.25"),
2493 cpp_dec_float("0.5"),
2494 one(),
2495 two(),
2496 cpp_dec_float(static_cast<boost::ulong_long_type>(4)),
2497 cpp_dec_float(static_cast<boost::ulong_long_type>(8)),
2498 cpp_dec_float(static_cast<boost::ulong_long_type>(16)),
2499 cpp_dec_float(static_cast<boost::ulong_long_type>(32)),
2500 cpp_dec_float(static_cast<boost::ulong_long_type>(64)),
2501 cpp_dec_float(static_cast<boost::ulong_long_type>(128)),
2502 cpp_dec_float(static_cast<boost::ulong_long_type>(256)),
2503 cpp_dec_float(static_cast<boost::ulong_long_type>(512)),
2504 cpp_dec_float(static_cast<boost::ulong_long_type>(1024)),
2505 cpp_dec_float(static_cast<boost::ulong_long_type>(2048)),
2506 cpp_dec_float(static_cast<boost::ulong_long_type>(4096)),
2507 cpp_dec_float(static_cast<boost::ulong_long_type>(8192)),
2508 cpp_dec_float(static_cast<boost::ulong_long_type>(16384)),
2509 cpp_dec_float(static_cast<boost::ulong_long_type>(32768)),
2510 cpp_dec_float(static_cast<boost::ulong_long_type>(65536)),
2511 cpp_dec_float(static_cast<boost::ulong_long_type>(131072)),
2512 cpp_dec_float(static_cast<boost::ulong_long_type>(262144)),
2513 cpp_dec_float(static_cast<boost::ulong_long_type>(524288)),
2514 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 20u)),
2515 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 21u)),
2516 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 22u)),
2517 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 23u)),
2518 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 24u)),
2519 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 25u)),
2520 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 26u)),
2521 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 27u)),
2522 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 28u)),
2523 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 29u)),
2524 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 30u)),
2525 cpp_dec_float(static_cast<boost::uint64_t>(1uL << 31u)),
2526 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 32u)),
2527 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 33u)),
2528 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 34u)),
2529 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 35u)),
2530 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 36u)),
2531 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 37u)),
2532 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 38u)),
2533 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 39u)),
2534 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 40u)),
2535 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 41u)),
2536 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 42u)),
2537 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 43u)),
2538 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 44u)),
2539 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 45u)),
2540 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 46u)),
2541 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 47u)),
2542 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 48u)),
2543 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 49u)),
2544 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 50u)),
2545 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 51u)),
2546 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 52u)),
2547 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 53u)),
2548 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 54u)),
2549 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 55u)),
2550 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 56u)),
2551 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 57u)),
2552 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 58u)),
2553 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 59u)),
2554 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 60u)),
2555 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 61u)),
2556 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 62u)),
2557 cpp_dec_float(static_cast<boost::uint64_t>(1uLL << 63u)),
2558 cpp_dec_float("1.844674407370955161600000000000000000000000000000000000000000000000000000000000000000000000000000000e19"),
2559 cpp_dec_float("3.689348814741910323200000000000000000000000000000000000000000000000000000000000000000000000000000000e19"),
2560 cpp_dec_float("7.378697629483820646400000000000000000000000000000000000000000000000000000000000000000000000000000000e19"),
2561 cpp_dec_float("1.475739525896764129280000000000000000000000000000000000000000000000000000000000000000000000000000000e20"),
2562 cpp_dec_float("2.951479051793528258560000000000000000000000000000000000000000000000000000000000000000000000000000000e20"),
2563 cpp_dec_float("5.902958103587056517120000000000000000000000000000000000000000000000000000000000000000000000000000000e20"),
2564 cpp_dec_float("1.180591620717411303424000000000000000000000000000000000000000000000000000000000000000000000000000000e21"),
2565 cpp_dec_float("2.361183241434822606848000000000000000000000000000000000000000000000000000000000000000000000000000000e21"),
2566 cpp_dec_float("4.722366482869645213696000000000000000000000000000000000000000000000000000000000000000000000000000000e21"),
2567 cpp_dec_float("9.444732965739290427392000000000000000000000000000000000000000000000000000000000000000000000000000000e21"),
2568 cpp_dec_float("1.888946593147858085478400000000000000000000000000000000000000000000000000000000000000000000000000000e22"),
2569 cpp_dec_float("3.777893186295716170956800000000000000000000000000000000000000000000000000000000000000000000000000000e22"),
2570 cpp_dec_float("7.555786372591432341913600000000000000000000000000000000000000000000000000000000000000000000000000000e22"),
2571 cpp_dec_float("1.511157274518286468382720000000000000000000000000000000000000000000000000000000000000000000000000000e23"),
2572 cpp_dec_float("3.022314549036572936765440000000000000000000000000000000000000000000000000000000000000000000000000000e23"),
2573 cpp_dec_float("6.044629098073145873530880000000000000000000000000000000000000000000000000000000000000000000000000000e23"),
2574 cpp_dec_float("1.208925819614629174706176000000000000000000000000000000000000000000000000000000000000000000000000000e24"),
2575 cpp_dec_float("2.417851639229258349412352000000000000000000000000000000000000000000000000000000000000000000000000000e24"),
2576 cpp_dec_float("4.835703278458516698824704000000000000000000000000000000000000000000000000000000000000000000000000000e24"),
2577 cpp_dec_float("9.671406556917033397649408000000000000000000000000000000000000000000000000000000000000000000000000000e24"),
2578 cpp_dec_float("1.934281311383406679529881600000000000000000000000000000000000000000000000000000000000000000000000000e25"),
2579 cpp_dec_float("3.868562622766813359059763200000000000000000000000000000000000000000000000000000000000000000000000000e25"),
2580 cpp_dec_float("7.737125245533626718119526400000000000000000000000000000000000000000000000000000000000000000000000000e25"),
2581 cpp_dec_float("1.547425049106725343623905280000000000000000000000000000000000000000000000000000000000000000000000000e26"),
2582 cpp_dec_float("3.094850098213450687247810560000000000000000000000000000000000000000000000000000000000000000000000000e26"),
2583 cpp_dec_float("6.189700196426901374495621120000000000000000000000000000000000000000000000000000000000000000000000000e26"),
2584 cpp_dec_float("1.237940039285380274899124224000000000000000000000000000000000000000000000000000000000000000000000000e27"),
2585 cpp_dec_float("2.475880078570760549798248448000000000000000000000000000000000000000000000000000000000000000000000000e27"),
2586 cpp_dec_float("4.951760157141521099596496896000000000000000000000000000000000000000000000000000000000000000000000000e27"),
2587 cpp_dec_float("9.903520314283042199192993792000000000000000000000000000000000000000000000000000000000000000000000000e27"),
2588 cpp_dec_float("1.980704062856608439838598758400000000000000000000000000000000000000000000000000000000000000000000000e28"),
2589 cpp_dec_float("3.961408125713216879677197516800000000000000000000000000000000000000000000000000000000000000000000000e28"),
2590 cpp_dec_float("7.922816251426433759354395033600000000000000000000000000000000000000000000000000000000000000000000000e28"),
2591 cpp_dec_float("1.584563250285286751870879006720000000000000000000000000000000000000000000000000000000000000000000000e29"),
2592 cpp_dec_float("3.169126500570573503741758013440000000000000000000000000000000000000000000000000000000000000000000000e29"),
2593 cpp_dec_float("6.338253001141147007483516026880000000000000000000000000000000000000000000000000000000000000000000000e29"),
2594 cpp_dec_float("1.267650600228229401496703205376000000000000000000000000000000000000000000000000000000000000000000000e30"),
2595 cpp_dec_float("2.535301200456458802993406410752000000000000000000000000000000000000000000000000000000000000000000000e30"),
2596 cpp_dec_float("5.070602400912917605986812821504000000000000000000000000000000000000000000000000000000000000000000000e30"),
2597 cpp_dec_float("1.014120480182583521197362564300800000000000000000000000000000000000000000000000000000000000000000000e31"),
2598 cpp_dec_float("2.028240960365167042394725128601600000000000000000000000000000000000000000000000000000000000000000000e31"),
2599 cpp_dec_float("4.056481920730334084789450257203200000000000000000000000000000000000000000000000000000000000000000000e31"),
2600 cpp_dec_float("8.112963841460668169578900514406400000000000000000000000000000000000000000000000000000000000000000000e31"),
2601 cpp_dec_float("1.622592768292133633915780102881280000000000000000000000000000000000000000000000000000000000000000000e32"),
2602 cpp_dec_float("3.245185536584267267831560205762560000000000000000000000000000000000000000000000000000000000000000000e32"),
2603 cpp_dec_float("6.490371073168534535663120411525120000000000000000000000000000000000000000000000000000000000000000000e32"),
2604 cpp_dec_float("1.298074214633706907132624082305024000000000000000000000000000000000000000000000000000000000000000000e33"),
2605 cpp_dec_float("2.596148429267413814265248164610048000000000000000000000000000000000000000000000000000000000000000000e33"),
2606 cpp_dec_float("5.192296858534827628530496329220096000000000000000000000000000000000000000000000000000000000000000000e33"),
2607 cpp_dec_float("1.038459371706965525706099265844019200000000000000000000000000000000000000000000000000000000000000000e34"),
2608 cpp_dec_float("2.076918743413931051412198531688038400000000000000000000000000000000000000000000000000000000000000000e34"),
2609 cpp_dec_float("4.153837486827862102824397063376076800000000000000000000000000000000000000000000000000000000000000000e34"),
2610 cpp_dec_float("8.307674973655724205648794126752153600000000000000000000000000000000000000000000000000000000000000000e34"),
2611 cpp_dec_float("1.661534994731144841129758825350430720000000000000000000000000000000000000000000000000000000000000000e35"),
2612 cpp_dec_float("3.323069989462289682259517650700861440000000000000000000000000000000000000000000000000000000000000000e35"),
2613 cpp_dec_float("6.646139978924579364519035301401722880000000000000000000000000000000000000000000000000000000000000000e35"),
2614 cpp_dec_float("1.329227995784915872903807060280344576000000000000000000000000000000000000000000000000000000000000000e36"),
2615 cpp_dec_float("2.658455991569831745807614120560689152000000000000000000000000000000000000000000000000000000000000000e36"),
2616 cpp_dec_float("5.316911983139663491615228241121378304000000000000000000000000000000000000000000000000000000000000000e36"),
2617 cpp_dec_float("1.063382396627932698323045648224275660800000000000000000000000000000000000000000000000000000000000000e37"),
2618 cpp_dec_float("2.126764793255865396646091296448551321600000000000000000000000000000000000000000000000000000000000000e37"),
2619 cpp_dec_float("4.253529586511730793292182592897102643200000000000000000000000000000000000000000000000000000000000000e37"),
2620 cpp_dec_float("8.507059173023461586584365185794205286400000000000000000000000000000000000000000000000000000000000000e37"),
2621 cpp_dec_float("1.701411834604692317316873037158841057280000000000000000000000000000000000000000000000000000000000000e38")
2622 }};
2623
2624 if((p > static_cast<boost::long_long_type>(-128)) && (p < static_cast<boost::long_long_type>(+128)))
2625 {
2626 return p2_data[static_cast<std::size_t>(p + ((p2_data.size() - 1u) / 2u))];
2627 }
2628 else
2629 {
2630 // Compute and return 2^p.
2631 if(p < static_cast<boost::long_long_type>(0))
2632 {
2633 return pow2(p: static_cast<boost::long_long_type>(-p)).calculate_inv();
2634 }
2635 else
2636 {
2637 cpp_dec_float<Digits10, ExponentType, Allocator> t;
2638 default_ops::detail::pow_imp(t, two(), p, mpl::true_());
2639 return t;
2640 }
2641 }
2642}
2643
2644
2645template <unsigned Digits10, class ExponentType, class Allocator>
2646inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
2647{
2648 result += o;
2649}
2650template <unsigned Digits10, class ExponentType, class Allocator>
2651inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
2652{
2653 result -= o;
2654}
2655template <unsigned Digits10, class ExponentType, class Allocator>
2656inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
2657{
2658 result *= o;
2659}
2660template <unsigned Digits10, class ExponentType, class Allocator>
2661inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
2662{
2663 result /= o;
2664}
2665
2666template <unsigned Digits10, class ExponentType, class Allocator>
2667inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o)
2668{
2669 result.add_unsigned_long_long(o);
2670}
2671template <unsigned Digits10, class ExponentType, class Allocator>
2672inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o)
2673{
2674 result.sub_unsigned_long_long(o);
2675}
2676template <unsigned Digits10, class ExponentType, class Allocator>
2677inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o)
2678{
2679 result.mul_unsigned_long_long(o);
2680}
2681template <unsigned Digits10, class ExponentType, class Allocator>
2682inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o)
2683{
2684 result.div_unsigned_long_long(o);
2685}
2686
2687template <unsigned Digits10, class ExponentType, class Allocator>
2688inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o)
2689{
2690 if(o < 0)
2691 result.sub_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(t: o));
2692 else
2693 result.add_unsigned_long_long(o);
2694}
2695template <unsigned Digits10, class ExponentType, class Allocator>
2696inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o)
2697{
2698 if(o < 0)
2699 result.add_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(t: o));
2700 else
2701 result.sub_unsigned_long_long(o);
2702}
2703template <unsigned Digits10, class ExponentType, class Allocator>
2704inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o)
2705{
2706 if(o < 0)
2707 {
2708 result.mul_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(t: o));
2709 result.negate();
2710 }
2711 else
2712 result.mul_unsigned_long_long(o);
2713}
2714template <unsigned Digits10, class ExponentType, class Allocator>
2715inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o)
2716{
2717 if(o < 0)
2718 {
2719 result.div_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(t: o));
2720 result.negate();
2721 }
2722 else
2723 result.div_unsigned_long_long(o);
2724}
2725
2726template <unsigned Digits10, class ExponentType, class Allocator>
2727inline void eval_convert_to(boost::ulong_long_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
2728{
2729 *result = val.extract_unsigned_long_long();
2730}
2731template <unsigned Digits10, class ExponentType, class Allocator>
2732inline void eval_convert_to(boost::long_long_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
2733{
2734 *result = val.extract_signed_long_long();
2735}
2736template <unsigned Digits10, class ExponentType, class Allocator>
2737inline void eval_convert_to(long double* result, cpp_dec_float<Digits10, ExponentType, Allocator>& val)
2738{
2739 *result = val.extract_long_double();
2740}
2741
2742//
2743// Non member function support:
2744//
2745template <unsigned Digits10, class ExponentType, class Allocator>
2746inline int eval_fpclassify(const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
2747{
2748 if((x.isinf)())
2749 return FP_INFINITE;
2750 if((x.isnan)())
2751 return FP_NAN;
2752 if(x.iszero())
2753 return FP_ZERO;
2754 return FP_NORMAL;
2755}
2756
2757template <unsigned Digits10, class ExponentType, class Allocator>
2758inline void eval_abs(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
2759{
2760 result = x;
2761 if(x.isneg())
2762 result.negate();
2763}
2764
2765template <unsigned Digits10, class ExponentType, class Allocator>
2766inline void eval_fabs(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
2767{
2768 result = x;
2769 if(x.isneg())
2770 result.negate();
2771}
2772
2773template <unsigned Digits10, class ExponentType, class Allocator>
2774inline void eval_sqrt(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
2775{
2776 result = x;
2777 result.calculate_sqrt();
2778}
2779
2780template <unsigned Digits10, class ExponentType, class Allocator>
2781inline void eval_floor(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
2782{
2783 result = x;
2784 if(!(x.isfinite)() || x.isint())
2785 {
2786 return;
2787 }
2788
2789 if(x.isneg())
2790 result -= cpp_dec_float<Digits10, ExponentType, Allocator>::one();
2791 result = result.extract_integer_part();
2792}
2793
2794template <unsigned Digits10, class ExponentType, class Allocator>
2795inline void eval_ceil(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
2796{
2797 result = x;
2798 if(!(x.isfinite)() || x.isint())
2799 {
2800 return;
2801 }
2802
2803 if(!x.isneg())
2804 result += cpp_dec_float<Digits10, ExponentType, Allocator>::one();
2805 result = result.extract_integer_part();
2806}
2807
2808template <unsigned Digits10, class ExponentType, class Allocator>
2809inline void eval_trunc(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
2810{
2811 if(!(x.isfinite)())
2812 {
2813 result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<cpp_dec_float<Digits10, ExponentType, Allocator> >(x), number<cpp_dec_float<Digits10, ExponentType, Allocator> >(x), boost::math::policies::policy<>()).backend();
2814 return;
2815 }
2816 else if(x.isint())
2817 {
2818 result = x;
2819 return;
2820 }
2821 result = x.extract_integer_part();
2822}
2823
2824template <unsigned Digits10, class ExponentType, class Allocator>
2825inline ExponentType eval_ilogb(const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
2826{
2827 // Set result, to the exponent of val:
2828 return val.order();
2829}
2830template <unsigned Digits10, class ExponentType, class Allocator, class ArgType>
2831inline void eval_scalbn(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val, ArgType e_)
2832{
2833 using default_ops::eval_multiply;
2834 const ExponentType e = e_;
2835 cpp_dec_float<Digits10, ExponentType, Allocator> t(1.0, e);
2836 eval_multiply(result, val, t);
2837}
2838
2839template <unsigned Digits10, class ExponentType, class Allocator, class ArgType>
2840inline void eval_ldexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, ArgType e)
2841{
2842 const boost::long_long_type the_exp = static_cast<boost::long_long_type>(e);
2843
2844 if((the_exp > (std::numeric_limits<ExponentType>::max)()) || (the_exp < (std::numeric_limits<ExponentType>::min)()))
2845 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Exponent value is out of range.")));
2846
2847 result = x;
2848
2849 if ((the_exp > static_cast<boost::long_long_type>(-std::numeric_limits<boost::long_long_type>::digits)) && (the_exp < static_cast<boost::long_long_type>(0)))
2850 result.div_unsigned_long_long(1ULL << static_cast<boost::long_long_type>(-the_exp));
2851 else if((the_exp < static_cast<boost::long_long_type>( std::numeric_limits<boost::long_long_type>::digits)) && (the_exp > static_cast<boost::long_long_type>(0)))
2852 result.mul_unsigned_long_long(1ULL << the_exp);
2853 else if(the_exp != static_cast<boost::long_long_type>(0))
2854 result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(e);
2855}
2856
2857template <unsigned Digits10, class ExponentType, class Allocator>
2858inline void eval_frexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, ExponentType* e)
2859{
2860 result = x;
2861 if(result.isneg())
2862 result.negate();
2863
2864 if(result.iszero())
2865 {
2866 *e = 0;
2867 return;
2868 }
2869
2870 ExponentType t = result.order();
2871 BOOST_MP_USING_ABS
2872 if(abs(t) < ((std::numeric_limits<ExponentType>::max)() / 1000))
2873 {
2874 t *= 1000;
2875 t /= 301;
2876 }
2877 else
2878 {
2879 t /= 301;
2880 t *= 1000;
2881 }
2882
2883 result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(-t);
2884
2885 if(result.iszero() || (result.isinf)() || (result.isnan)())
2886 {
2887 // pow2 overflowed, slip the calculation up:
2888 result = x;
2889 if(result.isneg())
2890 result.negate();
2891 t /= 2;
2892 result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(-t);
2893 }
2894 BOOST_MP_USING_ABS
2895 if(abs(result.order()) > 5)
2896 {
2897 // If our first estimate doesn't get close enough then try recursion until we do:
2898 ExponentType e2;
2899 cpp_dec_float<Digits10, ExponentType, Allocator> r2;
2900 eval_frexp(r2, result, &e2);
2901 // overflow protection:
2902 if((t > 0) && (e2 > 0) && (t > (std::numeric_limits<ExponentType>::max)() - e2))
2903 BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2."));
2904 if((t < 0) && (e2 < 0) && (t < (std::numeric_limits<ExponentType>::min)() - e2))
2905 BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2."));
2906 t += e2;
2907 result = r2;
2908 }
2909
2910 while(result.compare(cpp_dec_float<Digits10, ExponentType, Allocator>::one()) >= 0)
2911 {
2912 result /= cpp_dec_float<Digits10, ExponentType, Allocator>::two();
2913 ++t;
2914 }
2915 while(result.compare(cpp_dec_float<Digits10, ExponentType, Allocator>::half()) < 0)
2916 {
2917 result *= cpp_dec_float<Digits10, ExponentType, Allocator>::two();
2918 --t;
2919 }
2920 *e = t;
2921 if(x.isneg())
2922 result.negate();
2923}
2924
2925template <unsigned Digits10, class ExponentType, class Allocator>
2926inline typename disable_if<is_same<ExponentType, int> >::type eval_frexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, int* e)
2927{
2928 ExponentType t;
2929 eval_frexp(result, x, &t);
2930 if((t > (std::numeric_limits<int>::max)()) || (t < (std::numeric_limits<int>::min)()))
2931 BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is outside the range of an int"));
2932 *e = static_cast<int>(t);
2933}
2934
2935template <unsigned Digits10, class ExponentType, class Allocator>
2936inline bool eval_is_zero(const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
2937{
2938 return val.iszero();
2939}
2940template <unsigned Digits10, class ExponentType, class Allocator>
2941inline int eval_get_sign(const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
2942{
2943 return val.iszero() ? 0 : val.isneg() ? -1 : 1;
2944}
2945
2946} // namespace backends
2947
2948using boost::multiprecision::backends::cpp_dec_float;
2949
2950
2951typedef number<cpp_dec_float<50> > cpp_dec_float_50;
2952typedef number<cpp_dec_float<100> > cpp_dec_float_100;
2953
2954#ifdef BOOST_NO_SFINAE_EXPR
2955
2956namespace detail{
2957
2958template<unsigned D1, class E1, class A1, unsigned D2, class E2, class A2>
2959struct is_explicitly_convertible<cpp_dec_float<D1, E1, A1>, cpp_dec_float<D2, E2, A2> > : public mpl::true_ {};
2960
2961}
2962
2963#endif
2964
2965
2966}}
2967
2968namespace std
2969{
2970 template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
2971 class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >
2972 {
2973 public:
2974 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2975 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2976 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2977 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2978 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
2979 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2980 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2981 BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10;
2982 BOOST_STATIC_CONSTEXPR int digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10;
2983 BOOST_STATIC_CONSTEXPR int max_digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_total_digits10;
2984 BOOST_STATIC_CONSTEXPR ExponentType min_exponent = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp; // Type differs from int.
2985 BOOST_STATIC_CONSTEXPR ExponentType min_exponent10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10; // Type differs from int.
2986 BOOST_STATIC_CONSTEXPR ExponentType max_exponent = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp; // Type differs from int.
2987 BOOST_STATIC_CONSTEXPR ExponentType max_exponent10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10; // Type differs from int.
2988 BOOST_STATIC_CONSTEXPR int radix = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_radix;
2989 BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_indeterminate;
2990 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
2991 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
2992 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2993 BOOST_STATIC_CONSTEXPR std::float_denorm_style has_denorm = std::denorm_absent;
2994 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2995 BOOST_STATIC_CONSTEXPR bool traps = false;
2996 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2997
2998 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> (min) () { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::min)(); }
2999 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> (max) () { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::max)(); }
3000 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> lowest () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); }
3001 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> epsilon () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::eps(); }
3002 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> round_error () { return 0.5L; }
3003 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> infinity () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::inf(); }
3004 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> quiet_NaN () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::nan(); }
3005 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> signaling_NaN() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); }
3006 BOOST_STATIC_CONSTEXPR boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> denorm_min () { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); }
3007 };
3008
3009#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
3010
3011template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3012BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::digits;
3013template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3014BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::digits10;
3015template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3016BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_digits10;
3017template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3018BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_signed;
3019template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3020BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_integer;
3021template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3022BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_exact;
3023template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3024BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::radix;
3025template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3026BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::min_exponent;
3027template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3028BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::min_exponent10;
3029template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3030BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_exponent;
3031template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3032BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_exponent10;
3033template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3034BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_infinity;
3035template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3036BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_quiet_NaN;
3037template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3038BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_signaling_NaN;
3039template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3040BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_denorm;
3041template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3042BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_denorm_loss;
3043template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3044BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_iec559;
3045template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3046BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_bounded;
3047template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3048BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_modulo;
3049template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3050BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::traps;
3051template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3052BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::tinyness_before;
3053template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
3054BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::round_style;
3055
3056#endif
3057}
3058
3059namespace boost{ namespace math{
3060
3061namespace policies{
3062
3063template <unsigned Digits10, class ExponentType, class Allocator, class Policy, boost::multiprecision::expression_template_option ExpressionTemplates>
3064struct precision< boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates>, Policy>
3065{
3066 // Define a local copy of cpp_dec_float_digits10 because it might differ
3067 // from the template parameter Digits10 for small or large digit counts.
3068 static const boost::int32_t cpp_dec_float_digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10;
3069
3070 typedef typename Policy::precision_type precision_type;
3071 typedef digits2<((cpp_dec_float_digits10 + 1LL) * 1000LL) / 301LL> digits_2;
3072 typedef typename mpl::if_c<
3073 ((digits_2::value <= precision_type::value)
3074 || (Policy::precision_type::value <= 0)),
3075 // Default case, full precision for RealType:
3076 digits_2,
3077 // User customized precision:
3078 precision_type
3079 >::type type;
3080};
3081
3082} // namespace policies
3083
3084}} // namespaces boost::math
3085
3086#ifdef BOOST_MSVC
3087#pragma warning(pop)
3088#endif
3089
3090#endif
3091

source code of boost/boost/multiprecision/cpp_dec_float.hpp