annotate DEPENDENCIES/generic/include/boost/multiprecision/cpp_dec_float.hpp @ 133:4acb5d8d80b6 tip

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