annotate DEPENDENCIES/generic/include/boost/multiprecision/mpfr.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 // Copyright 2011 John Maddock. Distributed under the Boost
Chris@16 3 // Software License, Version 1.0. (See accompanying file
Chris@16 4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #ifndef BOOST_MATH_BN_MPFR_HPP
Chris@16 7 #define BOOST_MATH_BN_MPFR_HPP
Chris@16 8
Chris@16 9 #include <boost/multiprecision/number.hpp>
Chris@16 10 #include <boost/multiprecision/gmp.hpp>
Chris@16 11 #include <boost/math/special_functions/fpclassify.hpp>
Chris@16 12 #include <boost/cstdint.hpp>
Chris@16 13 #include <boost/multiprecision/detail/big_lanczos.hpp>
Chris@16 14 #include <boost/multiprecision/detail/digits.hpp>
Chris@16 15 #include <mpfr.h>
Chris@16 16 #include <cmath>
Chris@16 17 #include <algorithm>
Chris@16 18
Chris@16 19 namespace boost{
Chris@16 20 namespace multiprecision{
Chris@16 21
Chris@16 22 enum mpfr_allocation_type
Chris@16 23 {
Chris@16 24 allocate_stack,
Chris@16 25 allocate_dynamic
Chris@16 26 };
Chris@16 27
Chris@16 28 namespace backends{
Chris@16 29
Chris@16 30 template <unsigned digits10, mpfr_allocation_type AllocationType = allocate_dynamic>
Chris@16 31 struct mpfr_float_backend;
Chris@16 32
Chris@16 33 } // namespace backends
Chris@16 34
Chris@16 35 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 36 struct number_category<backends::mpfr_float_backend<digits10, AllocationType> > : public mpl::int_<number_kind_floating_point>{};
Chris@16 37
Chris@16 38 namespace backends{
Chris@16 39
Chris@16 40 namespace detail{
Chris@16 41
Chris@16 42 template <bool b>
Chris@16 43 struct mpfr_cleanup
Chris@16 44 {
Chris@16 45 struct initializer
Chris@16 46 {
Chris@16 47 initializer() {}
Chris@16 48 ~initializer(){ mpfr_free_cache(); }
Chris@16 49 void force_instantiate()const {}
Chris@16 50 };
Chris@16 51 static const initializer init;
Chris@16 52 static void force_instantiate() { init.force_instantiate(); }
Chris@16 53 };
Chris@16 54
Chris@16 55 template <bool b>
Chris@16 56 typename mpfr_cleanup<b>::initializer const mpfr_cleanup<b>::init;
Chris@16 57
Chris@16 58 inline long get_default_precision() { return 50; }
Chris@16 59
Chris@16 60 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 61 struct mpfr_float_imp;
Chris@16 62
Chris@16 63 template <unsigned digits10>
Chris@16 64 struct mpfr_float_imp<digits10, allocate_dynamic>
Chris@16 65 {
Chris@16 66 typedef mpl::list<long, long long> signed_types;
Chris@16 67 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
Chris@16 68 typedef mpl::list<double, long double> float_types;
Chris@16 69 typedef long exponent_type;
Chris@16 70
Chris@16 71 mpfr_float_imp()
Chris@16 72 {
Chris@16 73 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 74 }
Chris@16 75 mpfr_float_imp(unsigned prec)
Chris@16 76 {
Chris@16 77 mpfr_init2(m_data, prec);
Chris@16 78 }
Chris@16 79
Chris@16 80 mpfr_float_imp(const mpfr_float_imp& o)
Chris@16 81 {
Chris@16 82 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 83 if(o.m_data[0]._mpfr_d)
Chris@16 84 mpfr_set(m_data, o.m_data, GMP_RNDN);
Chris@16 85 }
Chris@16 86 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 87 mpfr_float_imp(mpfr_float_imp&& o) BOOST_NOEXCEPT
Chris@16 88 {
Chris@16 89 m_data[0] = o.m_data[0];
Chris@16 90 o.m_data[0]._mpfr_d = 0;
Chris@16 91 }
Chris@16 92 #endif
Chris@16 93 mpfr_float_imp& operator = (const mpfr_float_imp& o)
Chris@16 94 {
Chris@16 95 if(m_data[0]._mpfr_d == 0)
Chris@16 96 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 97 if(o.m_data[0]._mpfr_d)
Chris@16 98 mpfr_set(m_data, o.m_data, GMP_RNDN);
Chris@16 99 return *this;
Chris@16 100 }
Chris@16 101 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 102 mpfr_float_imp& operator = (mpfr_float_imp&& o) BOOST_NOEXCEPT
Chris@16 103 {
Chris@16 104 mpfr_swap(m_data, o.m_data);
Chris@16 105 return *this;
Chris@16 106 }
Chris@16 107 #endif
Chris@16 108 #ifdef _MPFR_H_HAVE_INTMAX_T
Chris@16 109 mpfr_float_imp& operator = (unsigned long long i)
Chris@16 110 {
Chris@16 111 if(m_data[0]._mpfr_d == 0)
Chris@16 112 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 113 mpfr_set_uj(m_data, i, GMP_RNDN);
Chris@16 114 return *this;
Chris@16 115 }
Chris@16 116 mpfr_float_imp& operator = (long long i)
Chris@16 117 {
Chris@16 118 if(m_data[0]._mpfr_d == 0)
Chris@16 119 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 120 mpfr_set_sj(m_data, i, GMP_RNDN);
Chris@16 121 return *this;
Chris@16 122 }
Chris@16 123 #else
Chris@16 124 mpfr_float_imp& operator = (unsigned long long i)
Chris@16 125 {
Chris@16 126 if(m_data[0]._mpfr_d == 0)
Chris@16 127 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 128 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
Chris@16 129 unsigned shift = 0;
Chris@16 130 mpfr_t t;
Chris@16 131 mpfr_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
Chris@16 132 mpfr_set_ui(m_data, 0, GMP_RNDN);
Chris@16 133 while(i)
Chris@16 134 {
Chris@16 135 mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
Chris@16 136 if(shift)
Chris@16 137 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
Chris@16 138 mpfr_add(m_data, m_data, t, GMP_RNDN);
Chris@16 139 shift += std::numeric_limits<unsigned>::digits;
Chris@16 140 i >>= std::numeric_limits<unsigned>::digits;
Chris@16 141 }
Chris@16 142 mpfr_clear(t);
Chris@16 143 return *this;
Chris@16 144 }
Chris@16 145 mpfr_float_imp& operator = (long long i)
Chris@16 146 {
Chris@16 147 if(m_data[0]._mpfr_d == 0)
Chris@16 148 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 149 bool neg = i < 0;
Chris@101 150 *this = boost::multiprecision::detail::unsigned_abs(i);
Chris@16 151 if(neg)
Chris@16 152 mpfr_neg(m_data, m_data, GMP_RNDN);
Chris@16 153 return *this;
Chris@16 154 }
Chris@16 155 #endif
Chris@16 156 mpfr_float_imp& operator = (unsigned long i)
Chris@16 157 {
Chris@16 158 if(m_data[0]._mpfr_d == 0)
Chris@16 159 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 160 mpfr_set_ui(m_data, i, GMP_RNDN);
Chris@16 161 return *this;
Chris@16 162 }
Chris@16 163 mpfr_float_imp& operator = (long i)
Chris@16 164 {
Chris@16 165 if(m_data[0]._mpfr_d == 0)
Chris@16 166 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 167 mpfr_set_si(m_data, i, GMP_RNDN);
Chris@16 168 return *this;
Chris@16 169 }
Chris@16 170 mpfr_float_imp& operator = (double d)
Chris@16 171 {
Chris@16 172 if(m_data[0]._mpfr_d == 0)
Chris@16 173 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 174 mpfr_set_d(m_data, d, GMP_RNDN);
Chris@16 175 return *this;
Chris@16 176 }
Chris@16 177 mpfr_float_imp& operator = (long double a)
Chris@16 178 {
Chris@16 179 if(m_data[0]._mpfr_d == 0)
Chris@16 180 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 181 mpfr_set_ld(m_data, a, GMP_RNDN);
Chris@16 182 return *this;
Chris@16 183 }
Chris@16 184 mpfr_float_imp& operator = (const char* s)
Chris@16 185 {
Chris@16 186 if(m_data[0]._mpfr_d == 0)
Chris@16 187 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 188 if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
Chris@16 189 {
Chris@16 190 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
Chris@16 191 }
Chris@16 192 return *this;
Chris@16 193 }
Chris@16 194 void swap(mpfr_float_imp& o) BOOST_NOEXCEPT
Chris@16 195 {
Chris@16 196 mpfr_swap(m_data, o.m_data);
Chris@16 197 }
Chris@16 198 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
Chris@16 199 {
Chris@16 200 BOOST_ASSERT(m_data[0]._mpfr_d);
Chris@16 201
Chris@16 202 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
Chris@16 203 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
Chris@16 204
Chris@16 205 std::streamsize org_digits(digits);
Chris@16 206
Chris@16 207 if(scientific && digits)
Chris@16 208 ++digits;
Chris@16 209
Chris@16 210 std::string result;
Chris@16 211 mp_exp_t e;
Chris@16 212 if(mpfr_inf_p(m_data))
Chris@16 213 {
Chris@16 214 if(mpfr_sgn(m_data) < 0)
Chris@16 215 result = "-inf";
Chris@16 216 else if(f & std::ios_base::showpos)
Chris@16 217 result = "+inf";
Chris@16 218 else
Chris@16 219 result = "inf";
Chris@16 220 return result;
Chris@16 221 }
Chris@16 222 if(mpfr_nan_p(m_data))
Chris@16 223 {
Chris@16 224 result = "nan";
Chris@16 225 return result;
Chris@16 226 }
Chris@16 227 if(mpfr_zero_p(m_data))
Chris@16 228 {
Chris@16 229 e = 0;
Chris@16 230 result = "0";
Chris@16 231 }
Chris@16 232 else
Chris@16 233 {
Chris@16 234 char* ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
Chris@16 235 --e; // To match with what our formatter expects.
Chris@16 236 if(fixed && e != -1)
Chris@16 237 {
Chris@16 238 // Oops we actually need a different number of digits to what we asked for:
Chris@16 239 mpfr_free_str(ps);
Chris@16 240 digits += e + 1;
Chris@16 241 if(digits == 0)
Chris@16 242 {
Chris@16 243 // We need to get *all* the digits and then possibly round up,
Chris@16 244 // we end up with either "0" or "1" as the result.
Chris@16 245 ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN);
Chris@16 246 --e;
Chris@16 247 unsigned offset = *ps == '-' ? 1 : 0;
Chris@16 248 if(ps[offset] > '5')
Chris@16 249 {
Chris@16 250 ++e;
Chris@16 251 ps[offset] = '1';
Chris@16 252 ps[offset + 1] = 0;
Chris@16 253 }
Chris@16 254 else if(ps[offset] == '5')
Chris@16 255 {
Chris@16 256 unsigned i = offset + 1;
Chris@16 257 bool round_up = false;
Chris@16 258 while(ps[i] != 0)
Chris@16 259 {
Chris@16 260 if(ps[i] != '0')
Chris@16 261 {
Chris@16 262 round_up = true;
Chris@16 263 break;
Chris@16 264 }
Chris@16 265 }
Chris@16 266 if(round_up)
Chris@16 267 {
Chris@16 268 ++e;
Chris@16 269 ps[offset] = '1';
Chris@16 270 ps[offset + 1] = 0;
Chris@16 271 }
Chris@16 272 else
Chris@16 273 {
Chris@16 274 ps[offset] = '0';
Chris@16 275 ps[offset + 1] = 0;
Chris@16 276 }
Chris@16 277 }
Chris@16 278 else
Chris@16 279 {
Chris@16 280 ps[offset] = '0';
Chris@16 281 ps[offset + 1] = 0;
Chris@16 282 }
Chris@16 283 }
Chris@16 284 else if(digits > 0)
Chris@16 285 {
Chris@16 286 ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
Chris@16 287 --e; // To match with what our formatter expects.
Chris@16 288 }
Chris@16 289 else
Chris@16 290 {
Chris@16 291 ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN);
Chris@16 292 --e;
Chris@16 293 unsigned offset = *ps == '-' ? 1 : 0;
Chris@16 294 ps[offset] = '0';
Chris@16 295 ps[offset + 1] = 0;
Chris@16 296 }
Chris@16 297 }
Chris@16 298 result = ps ? ps : "0";
Chris@16 299 if(ps)
Chris@16 300 mpfr_free_str(ps);
Chris@16 301 }
Chris@16 302 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
Chris@16 303 return result;
Chris@16 304 }
Chris@16 305 ~mpfr_float_imp() BOOST_NOEXCEPT
Chris@16 306 {
Chris@16 307 if(m_data[0]._mpfr_d)
Chris@16 308 mpfr_clear(m_data);
Chris@16 309 detail::mpfr_cleanup<true>::force_instantiate();
Chris@16 310 }
Chris@16 311 void negate() BOOST_NOEXCEPT
Chris@16 312 {
Chris@16 313 BOOST_ASSERT(m_data[0]._mpfr_d);
Chris@16 314 mpfr_neg(m_data, m_data, GMP_RNDN);
Chris@16 315 }
Chris@16 316 template <mpfr_allocation_type AllocationType>
Chris@16 317 int compare(const mpfr_float_backend<digits10, AllocationType>& o)const BOOST_NOEXCEPT
Chris@16 318 {
Chris@16 319 BOOST_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d);
Chris@16 320 return mpfr_cmp(m_data, o.m_data);
Chris@16 321 }
Chris@16 322 int compare(long i)const BOOST_NOEXCEPT
Chris@16 323 {
Chris@16 324 BOOST_ASSERT(m_data[0]._mpfr_d);
Chris@16 325 return mpfr_cmp_si(m_data, i);
Chris@16 326 }
Chris@16 327 int compare(unsigned long i)const BOOST_NOEXCEPT
Chris@16 328 {
Chris@16 329 BOOST_ASSERT(m_data[0]._mpfr_d);
Chris@16 330 return mpfr_cmp_ui(m_data, i);
Chris@16 331 }
Chris@16 332 template <class V>
Chris@16 333 int compare(V v)const BOOST_NOEXCEPT
Chris@16 334 {
Chris@16 335 mpfr_float_backend<digits10, allocate_dynamic> d;
Chris@16 336 d = v;
Chris@16 337 return compare(d);
Chris@16 338 }
Chris@16 339 mpfr_t& data() BOOST_NOEXCEPT
Chris@16 340 {
Chris@16 341 BOOST_ASSERT(m_data[0]._mpfr_d);
Chris@16 342 return m_data;
Chris@16 343 }
Chris@16 344 const mpfr_t& data()const BOOST_NOEXCEPT
Chris@16 345 {
Chris@16 346 BOOST_ASSERT(m_data[0]._mpfr_d);
Chris@16 347 return m_data;
Chris@16 348 }
Chris@16 349 protected:
Chris@16 350 mpfr_t m_data;
Chris@16 351 static unsigned& get_default_precision() BOOST_NOEXCEPT
Chris@16 352 {
Chris@16 353 static unsigned val = 50;
Chris@16 354 return val;
Chris@16 355 }
Chris@16 356 };
Chris@16 357
Chris@16 358 #ifdef BOOST_MSVC
Chris@16 359 #pragma warning(push)
Chris@16 360 #pragma warning(disable:4127) // Conditional expression is constant
Chris@16 361 #endif
Chris@16 362
Chris@16 363 template <unsigned digits10>
Chris@16 364 struct mpfr_float_imp<digits10, allocate_stack>
Chris@16 365 {
Chris@16 366 typedef mpl::list<long, long long> signed_types;
Chris@16 367 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
Chris@16 368 typedef mpl::list<double, long double> float_types;
Chris@16 369 typedef long exponent_type;
Chris@16 370
Chris@16 371 static const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u);
Chris@16 372 static const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t);
Chris@16 373
Chris@16 374 ~mpfr_float_imp() BOOST_NOEXCEPT
Chris@16 375 {
Chris@16 376 detail::mpfr_cleanup<true>::force_instantiate();
Chris@16 377 }
Chris@16 378 mpfr_float_imp()
Chris@16 379 {
Chris@16 380 mpfr_custom_init(m_buffer, digits2);
Chris@16 381 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
Chris@16 382 }
Chris@16 383
Chris@16 384 mpfr_float_imp(const mpfr_float_imp& o)
Chris@16 385 {
Chris@16 386 mpfr_custom_init(m_buffer, digits2);
Chris@16 387 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
Chris@16 388 mpfr_set(m_data, o.m_data, GMP_RNDN);
Chris@16 389 }
Chris@16 390 mpfr_float_imp& operator = (const mpfr_float_imp& o)
Chris@16 391 {
Chris@16 392 mpfr_set(m_data, o.m_data, GMP_RNDN);
Chris@16 393 return *this;
Chris@16 394 }
Chris@16 395 #ifdef _MPFR_H_HAVE_INTMAX_T
Chris@16 396 mpfr_float_imp& operator = (unsigned long long i)
Chris@16 397 {
Chris@16 398 mpfr_set_uj(m_data, i, GMP_RNDN);
Chris@16 399 return *this;
Chris@16 400 }
Chris@16 401 mpfr_float_imp& operator = (long long i)
Chris@16 402 {
Chris@16 403 mpfr_set_sj(m_data, i, GMP_RNDN);
Chris@16 404 return *this;
Chris@16 405 }
Chris@16 406 #else
Chris@16 407 mpfr_float_imp& operator = (unsigned long long i)
Chris@16 408 {
Chris@16 409 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
Chris@16 410 unsigned shift = 0;
Chris@16 411 mpfr_t t;
Chris@16 412 mp_limb_t t_limbs[limb_count];
Chris@16 413 mpfr_custom_init(t_limbs, digits2);
Chris@16 414 mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
Chris@16 415 mpfr_set_ui(m_data, 0, GMP_RNDN);
Chris@16 416 while(i)
Chris@16 417 {
Chris@16 418 mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
Chris@16 419 if(shift)
Chris@16 420 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
Chris@16 421 mpfr_add(m_data, m_data, t, GMP_RNDN);
Chris@16 422 shift += std::numeric_limits<unsigned>::digits;
Chris@16 423 i >>= std::numeric_limits<unsigned>::digits;
Chris@16 424 }
Chris@16 425 return *this;
Chris@16 426 }
Chris@16 427 mpfr_float_imp& operator = (long long i)
Chris@16 428 {
Chris@16 429 bool neg = i < 0;
Chris@101 430 *this = boost::multiprecision::detail::unsigned_abs(i);
Chris@16 431 if(neg)
Chris@16 432 mpfr_neg(m_data, m_data, GMP_RNDN);
Chris@16 433 return *this;
Chris@16 434 }
Chris@16 435 #endif
Chris@16 436 mpfr_float_imp& operator = (unsigned long i)
Chris@16 437 {
Chris@16 438 mpfr_set_ui(m_data, i, GMP_RNDN);
Chris@16 439 return *this;
Chris@16 440 }
Chris@16 441 mpfr_float_imp& operator = (long i)
Chris@16 442 {
Chris@16 443 mpfr_set_si(m_data, i, GMP_RNDN);
Chris@16 444 return *this;
Chris@16 445 }
Chris@16 446 mpfr_float_imp& operator = (double d)
Chris@16 447 {
Chris@16 448 mpfr_set_d(m_data, d, GMP_RNDN);
Chris@16 449 return *this;
Chris@16 450 }
Chris@16 451 mpfr_float_imp& operator = (long double a)
Chris@16 452 {
Chris@16 453 mpfr_set_ld(m_data, a, GMP_RNDN);
Chris@16 454 return *this;
Chris@16 455 }
Chris@16 456 mpfr_float_imp& operator = (const char* s)
Chris@16 457 {
Chris@16 458 if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
Chris@16 459 {
Chris@16 460 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
Chris@16 461 }
Chris@16 462 return *this;
Chris@16 463 }
Chris@16 464 void swap(mpfr_float_imp& o) BOOST_NOEXCEPT
Chris@16 465 {
Chris@16 466 // We have to swap by copying:
Chris@16 467 mpfr_float_imp t(*this);
Chris@16 468 *this = o;
Chris@16 469 o = t;
Chris@16 470 }
Chris@16 471 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
Chris@16 472 {
Chris@16 473 BOOST_ASSERT(m_data[0]._mpfr_d);
Chris@16 474
Chris@16 475 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
Chris@16 476 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
Chris@16 477
Chris@16 478 std::streamsize org_digits(digits);
Chris@16 479
Chris@16 480 if(scientific && digits)
Chris@16 481 ++digits;
Chris@16 482
Chris@16 483 std::string result;
Chris@16 484 mp_exp_t e;
Chris@16 485 if(mpfr_inf_p(m_data))
Chris@16 486 {
Chris@16 487 if(mpfr_sgn(m_data) < 0)
Chris@16 488 result = "-inf";
Chris@16 489 else if(f & std::ios_base::showpos)
Chris@16 490 result = "+inf";
Chris@16 491 else
Chris@16 492 result = "inf";
Chris@16 493 return result;
Chris@16 494 }
Chris@16 495 if(mpfr_nan_p(m_data))
Chris@16 496 {
Chris@16 497 result = "nan";
Chris@16 498 return result;
Chris@16 499 }
Chris@16 500 if(mpfr_zero_p(m_data))
Chris@16 501 {
Chris@16 502 e = 0;
Chris@16 503 result = "0";
Chris@16 504 }
Chris@16 505 else
Chris@16 506 {
Chris@16 507 char* ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
Chris@16 508 --e; // To match with what our formatter expects.
Chris@16 509 if(fixed && e != -1)
Chris@16 510 {
Chris@16 511 // Oops we actually need a different number of digits to what we asked for:
Chris@16 512 mpfr_free_str(ps);
Chris@16 513 digits += e + 1;
Chris@16 514 if(digits == 0)
Chris@16 515 {
Chris@16 516 // We need to get *all* the digits and then possibly round up,
Chris@16 517 // we end up with either "0" or "1" as the result.
Chris@16 518 ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN);
Chris@16 519 --e;
Chris@16 520 unsigned offset = *ps == '-' ? 1 : 0;
Chris@16 521 if(ps[offset] > '5')
Chris@16 522 {
Chris@16 523 ++e;
Chris@16 524 ps[offset] = '1';
Chris@16 525 ps[offset + 1] = 0;
Chris@16 526 }
Chris@16 527 else if(ps[offset] == '5')
Chris@16 528 {
Chris@16 529 unsigned i = offset + 1;
Chris@16 530 bool round_up = false;
Chris@16 531 while(ps[i] != 0)
Chris@16 532 {
Chris@16 533 if(ps[i] != '0')
Chris@16 534 {
Chris@16 535 round_up = true;
Chris@16 536 break;
Chris@16 537 }
Chris@16 538 }
Chris@16 539 if(round_up)
Chris@16 540 {
Chris@16 541 ++e;
Chris@16 542 ps[offset] = '1';
Chris@16 543 ps[offset + 1] = 0;
Chris@16 544 }
Chris@16 545 else
Chris@16 546 {
Chris@16 547 ps[offset] = '0';
Chris@16 548 ps[offset + 1] = 0;
Chris@16 549 }
Chris@16 550 }
Chris@16 551 else
Chris@16 552 {
Chris@16 553 ps[offset] = '0';
Chris@16 554 ps[offset + 1] = 0;
Chris@16 555 }
Chris@16 556 }
Chris@16 557 else if(digits > 0)
Chris@16 558 {
Chris@16 559 ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
Chris@16 560 --e; // To match with what our formatter expects.
Chris@16 561 }
Chris@16 562 else
Chris@16 563 {
Chris@16 564 ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN);
Chris@16 565 --e;
Chris@16 566 unsigned offset = *ps == '-' ? 1 : 0;
Chris@16 567 ps[offset] = '0';
Chris@16 568 ps[offset + 1] = 0;
Chris@16 569 }
Chris@16 570 }
Chris@16 571 result = ps ? ps : "0";
Chris@16 572 if(ps)
Chris@16 573 mpfr_free_str(ps);
Chris@16 574 }
Chris@16 575 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
Chris@16 576 return result;
Chris@16 577 }
Chris@16 578 void negate() BOOST_NOEXCEPT
Chris@16 579 {
Chris@16 580 mpfr_neg(m_data, m_data, GMP_RNDN);
Chris@16 581 }
Chris@16 582 template <mpfr_allocation_type AllocationType>
Chris@16 583 int compare(const mpfr_float_backend<digits10, AllocationType>& o)const BOOST_NOEXCEPT
Chris@16 584 {
Chris@16 585 return mpfr_cmp(m_data, o.m_data);
Chris@16 586 }
Chris@16 587 int compare(long i)const BOOST_NOEXCEPT
Chris@16 588 {
Chris@16 589 return mpfr_cmp_si(m_data, i);
Chris@16 590 }
Chris@16 591 int compare(unsigned long i)const BOOST_NOEXCEPT
Chris@16 592 {
Chris@16 593 return mpfr_cmp_ui(m_data, i);
Chris@16 594 }
Chris@16 595 template <class V>
Chris@16 596 int compare(V v)const BOOST_NOEXCEPT
Chris@16 597 {
Chris@16 598 mpfr_float_backend<digits10, allocate_stack> d;
Chris@16 599 d = v;
Chris@16 600 return compare(d);
Chris@16 601 }
Chris@16 602 mpfr_t& data() BOOST_NOEXCEPT
Chris@16 603 {
Chris@16 604 return m_data;
Chris@16 605 }
Chris@16 606 const mpfr_t& data()const BOOST_NOEXCEPT
Chris@16 607 {
Chris@16 608 return m_data;
Chris@16 609 }
Chris@16 610 protected:
Chris@16 611 mpfr_t m_data;
Chris@16 612 mp_limb_t m_buffer[limb_count];
Chris@16 613 };
Chris@16 614
Chris@16 615 #ifdef BOOST_MSVC
Chris@16 616 #pragma warning(pop)
Chris@16 617 #endif
Chris@16 618
Chris@16 619 } // namespace detail
Chris@16 620
Chris@16 621 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 622 struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
Chris@16 623 {
Chris@16 624 mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
Chris@16 625 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
Chris@16 626 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 627 mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o)) {}
Chris@16 628 #endif
Chris@16 629 template <unsigned D, mpfr_allocation_type AT>
Chris@16 630 mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename enable_if_c<D <= digits10>::type* = 0)
Chris@16 631 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 632 {
Chris@16 633 mpfr_set(this->m_data, val.data(), GMP_RNDN);
Chris@16 634 }
Chris@16 635 template <unsigned D, mpfr_allocation_type AT>
Chris@16 636 explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename disable_if_c<D <= digits10>::type* = 0)
Chris@16 637 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 638 {
Chris@16 639 mpfr_set(this->m_data, val.data(), GMP_RNDN);
Chris@16 640 }
Chris@16 641 template <unsigned D>
Chris@16 642 mpfr_float_backend(const gmp_float<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
Chris@16 643 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 644 {
Chris@16 645 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
Chris@16 646 }
Chris@16 647 template <unsigned D>
Chris@16 648 mpfr_float_backend(const gmp_float<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
Chris@16 649 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 650 {
Chris@16 651 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
Chris@16 652 }
Chris@16 653 mpfr_float_backend(const gmp_int& val)
Chris@16 654 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 655 {
Chris@16 656 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
Chris@16 657 }
Chris@16 658 mpfr_float_backend(const gmp_rational& val)
Chris@16 659 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 660 {
Chris@16 661 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
Chris@16 662 }
Chris@16 663 mpfr_float_backend(const mpfr_t val)
Chris@16 664 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 665 {
Chris@16 666 mpfr_set(this->m_data, val, GMP_RNDN);
Chris@16 667 }
Chris@16 668 mpfr_float_backend(const mpf_t val)
Chris@16 669 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 670 {
Chris@16 671 mpfr_set_f(this->m_data, val, GMP_RNDN);
Chris@16 672 }
Chris@16 673 mpfr_float_backend(const mpz_t val)
Chris@16 674 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 675 {
Chris@16 676 mpfr_set_z(this->m_data, val, GMP_RNDN);
Chris@16 677 }
Chris@16 678 mpfr_float_backend(const mpq_t val)
Chris@16 679 : detail::mpfr_float_imp<digits10, AllocationType>()
Chris@16 680 {
Chris@16 681 mpfr_set_q(this->m_data, val, GMP_RNDN);
Chris@16 682 }
Chris@16 683 mpfr_float_backend& operator=(const mpfr_float_backend& o)
Chris@16 684 {
Chris@16 685 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
Chris@16 686 return *this;
Chris@16 687 }
Chris@16 688 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 689 mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT
Chris@16 690 {
Chris@16 691 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
Chris@16 692 return *this;
Chris@16 693 }
Chris@16 694 #endif
Chris@16 695 template <class V>
Chris@16 696 mpfr_float_backend& operator=(const V& v)
Chris@16 697 {
Chris@16 698 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
Chris@16 699 return *this;
Chris@16 700 }
Chris@16 701 mpfr_float_backend& operator=(const mpfr_t val)
Chris@16 702 {
Chris@16 703 if(this->m_data[0]._mpfr_d == 0)
Chris@16 704 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 705 mpfr_set(this->m_data, val, GMP_RNDN);
Chris@16 706 return *this;
Chris@16 707 }
Chris@16 708 mpfr_float_backend& operator=(const mpf_t val)
Chris@16 709 {
Chris@16 710 if(this->m_data[0]._mpfr_d == 0)
Chris@16 711 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 712 mpfr_set_f(this->m_data, val, GMP_RNDN);
Chris@16 713 return *this;
Chris@16 714 }
Chris@16 715 mpfr_float_backend& operator=(const mpz_t val)
Chris@16 716 {
Chris@16 717 if(this->m_data[0]._mpfr_d == 0)
Chris@16 718 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 719 mpfr_set_z(this->m_data, val, GMP_RNDN);
Chris@16 720 return *this;
Chris@16 721 }
Chris@16 722 mpfr_float_backend& operator=(const mpq_t val)
Chris@16 723 {
Chris@16 724 if(this->m_data[0]._mpfr_d == 0)
Chris@16 725 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 726 mpfr_set_q(this->m_data, val, GMP_RNDN);
Chris@16 727 return *this;
Chris@16 728 }
Chris@16 729 // We don't change our precision here, this is a fixed precision type:
Chris@16 730 template <unsigned D, mpfr_allocation_type AT>
Chris@16 731 mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
Chris@16 732 {
Chris@16 733 if(this->m_data[0]._mpfr_d == 0)
Chris@16 734 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 735 mpfr_set(this->m_data, val.data(), GMP_RNDN);
Chris@16 736 return *this;
Chris@16 737 }
Chris@16 738 template <unsigned D>
Chris@16 739 mpfr_float_backend& operator=(const gmp_float<D>& val)
Chris@16 740 {
Chris@16 741 if(this->m_data[0]._mpfr_d == 0)
Chris@16 742 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 743 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
Chris@16 744 return *this;
Chris@16 745 }
Chris@16 746 mpfr_float_backend& operator=(const gmp_int& val)
Chris@16 747 {
Chris@16 748 if(this->m_data[0]._mpfr_d == 0)
Chris@16 749 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 750 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
Chris@16 751 return *this;
Chris@16 752 }
Chris@16 753 mpfr_float_backend& operator=(const gmp_rational& val)
Chris@16 754 {
Chris@16 755 if(this->m_data[0]._mpfr_d == 0)
Chris@16 756 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 757 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
Chris@16 758 return *this;
Chris@16 759 }
Chris@16 760 };
Chris@16 761
Chris@16 762 template <>
Chris@16 763 struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
Chris@16 764 {
Chris@16 765 mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
Chris@16 766 mpfr_float_backend(const mpfr_t val)
Chris@16 767 : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val))
Chris@16 768 {
Chris@16 769 mpfr_set(this->m_data, val, GMP_RNDN);
Chris@16 770 }
Chris@16 771 mpfr_float_backend(const mpf_t val)
Chris@16 772 : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val))
Chris@16 773 {
Chris@16 774 mpfr_set_f(this->m_data, val, GMP_RNDN);
Chris@16 775 }
Chris@16 776 mpfr_float_backend(const mpz_t val)
Chris@16 777 : detail::mpfr_float_imp<0, allocate_dynamic>()
Chris@16 778 {
Chris@16 779 mpfr_set_z(this->m_data, val, GMP_RNDN);
Chris@16 780 }
Chris@16 781 mpfr_float_backend(const mpq_t val)
Chris@16 782 : detail::mpfr_float_imp<0, allocate_dynamic>()
Chris@16 783 {
Chris@16 784 mpfr_set_q(this->m_data, val, GMP_RNDN);
Chris@16 785 }
Chris@16 786 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
Chris@16 787 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 788 mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o)) {}
Chris@16 789 #endif
Chris@16 790 mpfr_float_backend(const mpfr_float_backend& o, unsigned digits10)
Chris@16 791 : detail::mpfr_float_imp<0, allocate_dynamic>(digits10)
Chris@16 792 {
Chris@16 793 *this = o;
Chris@16 794 }
Chris@16 795 template <unsigned D>
Chris@16 796 mpfr_float_backend(const mpfr_float_backend<D>& val)
Chris@16 797 : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val.data()))
Chris@16 798 {
Chris@16 799 mpfr_set(this->m_data, val.data(), GMP_RNDN);
Chris@16 800 }
Chris@16 801 template <unsigned D>
Chris@16 802 mpfr_float_backend(const gmp_float<D>& val)
Chris@16 803 : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val.data()))
Chris@16 804 {
Chris@16 805 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
Chris@16 806 }
Chris@16 807 mpfr_float_backend(const gmp_int& val)
Chris@16 808 : detail::mpfr_float_imp<0, allocate_dynamic>()
Chris@16 809 {
Chris@16 810 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
Chris@16 811 }
Chris@16 812 mpfr_float_backend(const gmp_rational& val)
Chris@16 813 : detail::mpfr_float_imp<0, allocate_dynamic>()
Chris@16 814 {
Chris@16 815 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
Chris@16 816 }
Chris@16 817
Chris@16 818 mpfr_float_backend& operator=(const mpfr_float_backend& o)
Chris@16 819 {
Chris@16 820 if(this->m_data[0]._mpfr_d == 0)
Chris@16 821 mpfr_init2(this->m_data, mpfr_get_prec(o.data()));
Chris@16 822 else
Chris@16 823 mpfr_set_prec(this->m_data, mpfr_get_prec(o.data()));
Chris@16 824 mpfr_set(this->m_data, o.data(), GMP_RNDN);
Chris@16 825 return *this;
Chris@16 826 }
Chris@16 827 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 828 mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT
Chris@16 829 {
Chris@16 830 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = static_cast<detail::mpfr_float_imp<0, allocate_dynamic> &&>(o);
Chris@16 831 return *this;
Chris@16 832 }
Chris@16 833 #endif
Chris@16 834 template <class V>
Chris@16 835 mpfr_float_backend& operator=(const V& v)
Chris@16 836 {
Chris@16 837 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
Chris@16 838 return *this;
Chris@16 839 }
Chris@16 840 mpfr_float_backend& operator=(const mpfr_t val)
Chris@16 841 {
Chris@16 842 if(this->m_data[0]._mpfr_d == 0)
Chris@16 843 mpfr_init2(this->m_data, mpfr_get_prec(val));
Chris@16 844 else
Chris@16 845 mpfr_set_prec(this->m_data, mpfr_get_prec(val));
Chris@16 846 mpfr_set(this->m_data, val, GMP_RNDN);
Chris@16 847 return *this;
Chris@16 848 }
Chris@16 849 mpfr_float_backend& operator=(const mpf_t val)
Chris@16 850 {
Chris@16 851 if(this->m_data[0]._mpfr_d == 0)
Chris@16 852 mpfr_init2(this->m_data, mpf_get_prec(val));
Chris@16 853 else
Chris@16 854 mpfr_set_prec(this->m_data, mpf_get_prec(val));
Chris@16 855 mpfr_set_f(this->m_data, val, GMP_RNDN);
Chris@16 856 return *this;
Chris@16 857 }
Chris@16 858 mpfr_float_backend& operator=(const mpz_t val)
Chris@16 859 {
Chris@16 860 if(this->m_data[0]._mpfr_d == 0)
Chris@16 861 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 862 mpfr_set_z(this->m_data, val, GMP_RNDN);
Chris@16 863 return *this;
Chris@16 864 }
Chris@16 865 mpfr_float_backend& operator=(const mpq_t val)
Chris@16 866 {
Chris@16 867 if(this->m_data[0]._mpfr_d == 0)
Chris@16 868 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 869 mpfr_set_q(this->m_data, val, GMP_RNDN);
Chris@16 870 return *this;
Chris@16 871 }
Chris@16 872 template <unsigned D>
Chris@16 873 mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
Chris@16 874 {
Chris@16 875 if(this->m_data[0]._mpfr_d == 0)
Chris@16 876 mpfr_init2(this->m_data, mpfr_get_prec(val.data()));
Chris@16 877 else
Chris@16 878 mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
Chris@16 879 mpfr_set(this->m_data, val.data(), GMP_RNDN);
Chris@16 880 return *this;
Chris@16 881 }
Chris@16 882 template <unsigned D>
Chris@16 883 mpfr_float_backend& operator=(const gmp_float<D>& val)
Chris@16 884 {
Chris@16 885 if(this->m_data[0]._mpfr_d == 0)
Chris@16 886 mpfr_init2(this->m_data, mpf_get_prec(val.data()));
Chris@16 887 else
Chris@16 888 mpfr_set_prec(this->m_data, mpf_get_prec(val.data()));
Chris@16 889 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
Chris@16 890 return *this;
Chris@16 891 }
Chris@16 892 mpfr_float_backend& operator=(const gmp_int& val)
Chris@16 893 {
Chris@16 894 if(this->m_data[0]._mpfr_d == 0)
Chris@16 895 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 896 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
Chris@16 897 return *this;
Chris@16 898 }
Chris@16 899 mpfr_float_backend& operator=(const gmp_rational& val)
Chris@16 900 {
Chris@16 901 if(this->m_data[0]._mpfr_d == 0)
Chris@16 902 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 903 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
Chris@16 904 return *this;
Chris@16 905 }
Chris@16 906 static unsigned default_precision() BOOST_NOEXCEPT
Chris@16 907 {
Chris@16 908 return get_default_precision();
Chris@16 909 }
Chris@16 910 static void default_precision(unsigned v) BOOST_NOEXCEPT
Chris@16 911 {
Chris@16 912 get_default_precision() = v;
Chris@16 913 }
Chris@16 914 unsigned precision()const BOOST_NOEXCEPT
Chris@16 915 {
Chris@16 916 return multiprecision::detail::digits2_2_10(mpfr_get_prec(this->m_data));
Chris@16 917 }
Chris@16 918 void precision(unsigned digits10) BOOST_NOEXCEPT
Chris@16 919 {
Chris@16 920 mpfr_prec_round(this->m_data, multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
Chris@16 921 }
Chris@16 922 };
Chris@16 923
Chris@16 924 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
Chris@16 925 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
Chris@16 926 {
Chris@16 927 return a.compare(b) == 0;
Chris@16 928 }
Chris@16 929 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
Chris@16 930 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
Chris@16 931 {
Chris@16 932 return a.compare(b) < 0;
Chris@16 933 }
Chris@16 934 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
Chris@16 935 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
Chris@16 936 {
Chris@16 937 return a.compare(b) > 0;
Chris@16 938 }
Chris@16 939
Chris@16 940 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 941 inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
Chris@16 942 {
Chris@16 943 mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
Chris@16 944 }
Chris@16 945 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 946 inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
Chris@16 947 {
Chris@16 948 mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
Chris@16 949 }
Chris@16 950 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 951 inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
Chris@16 952 {
Chris@16 953 if((void*)&o == (void*)&result)
Chris@16 954 mpfr_sqr(result.data(), o.data(), GMP_RNDN);
Chris@16 955 else
Chris@16 956 mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
Chris@16 957 }
Chris@16 958 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 959 inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
Chris@16 960 {
Chris@16 961 mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
Chris@16 962 }
Chris@16 963 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 964 inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
Chris@16 965 {
Chris@16 966 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
Chris@16 967 }
Chris@16 968 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 969 inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
Chris@16 970 {
Chris@16 971 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
Chris@16 972 }
Chris@16 973 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 974 inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
Chris@16 975 {
Chris@16 976 mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
Chris@16 977 }
Chris@16 978 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 979 inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
Chris@16 980 {
Chris@16 981 mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
Chris@16 982 }
Chris@16 983 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 984 inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
Chris@16 985 {
Chris@16 986 if(i > 0)
Chris@16 987 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
Chris@16 988 else
Chris@101 989 mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
Chris@16 990 }
Chris@16 991 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 992 inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
Chris@16 993 {
Chris@16 994 if(i > 0)
Chris@16 995 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
Chris@16 996 else
Chris@101 997 mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
Chris@16 998 }
Chris@16 999 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1000 inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
Chris@16 1001 {
Chris@101 1002 mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
Chris@16 1003 if(i < 0)
Chris@16 1004 mpfr_neg(result.data(), result.data(), GMP_RNDN);
Chris@16 1005 }
Chris@16 1006 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1007 inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
Chris@16 1008 {
Chris@101 1009 mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
Chris@16 1010 if(i < 0)
Chris@16 1011 mpfr_neg(result.data(), result.data(), GMP_RNDN);
Chris@16 1012 }
Chris@16 1013 //
Chris@16 1014 // Specialised 3 arg versions of the basic operators:
Chris@16 1015 //
Chris@16 1016 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
Chris@16 1017 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
Chris@16 1018 {
Chris@16 1019 mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
Chris@16 1020 }
Chris@16 1021 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1022 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
Chris@16 1023 {
Chris@16 1024 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
Chris@16 1025 }
Chris@16 1026 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1027 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
Chris@16 1028 {
Chris@16 1029 if(y < 0)
Chris@101 1030 mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
Chris@16 1031 else
Chris@16 1032 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
Chris@16 1033 }
Chris@16 1034 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1035 inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
Chris@16 1036 {
Chris@16 1037 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
Chris@16 1038 }
Chris@16 1039 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1040 inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
Chris@16 1041 {
Chris@16 1042 if(x < 0)
Chris@16 1043 {
Chris@101 1044 mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
Chris@16 1045 mpfr_neg(a.data(), a.data(), GMP_RNDN);
Chris@16 1046 }
Chris@16 1047 else
Chris@16 1048 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
Chris@16 1049 }
Chris@16 1050 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
Chris@16 1051 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
Chris@16 1052 {
Chris@16 1053 mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
Chris@16 1054 }
Chris@16 1055 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1056 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
Chris@16 1057 {
Chris@16 1058 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
Chris@16 1059 }
Chris@16 1060 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1061 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
Chris@16 1062 {
Chris@16 1063 if(y < 0)
Chris@101 1064 mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
Chris@16 1065 else
Chris@16 1066 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
Chris@16 1067 }
Chris@16 1068 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1069 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
Chris@16 1070 {
Chris@16 1071 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
Chris@16 1072 }
Chris@16 1073 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1074 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
Chris@16 1075 {
Chris@16 1076 if(x < 0)
Chris@16 1077 {
Chris@101 1078 mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
Chris@16 1079 mpfr_neg(a.data(), a.data(), GMP_RNDN);
Chris@16 1080 }
Chris@16 1081 else
Chris@16 1082 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
Chris@16 1083 }
Chris@16 1084
Chris@16 1085 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
Chris@16 1086 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
Chris@16 1087 {
Chris@16 1088 if((void*)&x == (void*)&y)
Chris@16 1089 mpfr_sqr(a.data(), x.data(), GMP_RNDN);
Chris@16 1090 else
Chris@16 1091 mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
Chris@16 1092 }
Chris@16 1093 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1094 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
Chris@16 1095 {
Chris@16 1096 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
Chris@16 1097 }
Chris@16 1098 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1099 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
Chris@16 1100 {
Chris@16 1101 if(y < 0)
Chris@16 1102 {
Chris@101 1103 mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
Chris@16 1104 a.negate();
Chris@16 1105 }
Chris@16 1106 else
Chris@16 1107 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
Chris@16 1108 }
Chris@16 1109 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1110 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
Chris@16 1111 {
Chris@16 1112 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
Chris@16 1113 }
Chris@16 1114 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1115 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
Chris@16 1116 {
Chris@16 1117 if(x < 0)
Chris@16 1118 {
Chris@101 1119 mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
Chris@16 1120 mpfr_neg(a.data(), a.data(), GMP_RNDN);
Chris@16 1121 }
Chris@16 1122 else
Chris@16 1123 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
Chris@16 1124 }
Chris@16 1125
Chris@16 1126 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
Chris@16 1127 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
Chris@16 1128 {
Chris@16 1129 mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
Chris@16 1130 }
Chris@16 1131 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1132 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
Chris@16 1133 {
Chris@16 1134 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
Chris@16 1135 }
Chris@16 1136 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1137 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
Chris@16 1138 {
Chris@16 1139 if(y < 0)
Chris@16 1140 {
Chris@101 1141 mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
Chris@16 1142 a.negate();
Chris@16 1143 }
Chris@16 1144 else
Chris@16 1145 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
Chris@16 1146 }
Chris@16 1147 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1148 inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
Chris@16 1149 {
Chris@16 1150 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
Chris@16 1151 }
Chris@16 1152 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1153 inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
Chris@16 1154 {
Chris@16 1155 if(x < 0)
Chris@16 1156 {
Chris@101 1157 mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
Chris@16 1158 mpfr_neg(a.data(), a.data(), GMP_RNDN);
Chris@16 1159 }
Chris@16 1160 else
Chris@16 1161 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
Chris@16 1162 }
Chris@16 1163
Chris@16 1164 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1165 inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
Chris@16 1166 {
Chris@16 1167 return 0 != mpfr_zero_p(val.data());
Chris@16 1168 }
Chris@16 1169 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1170 inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
Chris@16 1171 {
Chris@16 1172 return mpfr_sgn(val.data());
Chris@16 1173 }
Chris@16 1174
Chris@16 1175 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1176 inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
Chris@16 1177 {
Chris@16 1178 if(mpfr_nan_p(val.data()))
Chris@16 1179 {
Chris@16 1180 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
Chris@16 1181 }
Chris@16 1182 *result = mpfr_get_ui(val.data(), GMP_RNDZ);
Chris@16 1183 }
Chris@16 1184 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1185 inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
Chris@16 1186 {
Chris@16 1187 if(mpfr_nan_p(val.data()))
Chris@16 1188 {
Chris@16 1189 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
Chris@16 1190 }
Chris@16 1191 *result = mpfr_get_si(val.data(), GMP_RNDZ);
Chris@16 1192 }
Chris@16 1193 #ifdef _MPFR_H_HAVE_INTMAX_T
Chris@16 1194 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1195 inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
Chris@16 1196 {
Chris@16 1197 if(mpfr_nan_p(val.data()))
Chris@16 1198 {
Chris@16 1199 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
Chris@16 1200 }
Chris@16 1201 *result = mpfr_get_uj(val.data(), GMP_RNDZ);
Chris@16 1202 }
Chris@16 1203 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1204 inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
Chris@16 1205 {
Chris@16 1206 if(mpfr_nan_p(val.data()))
Chris@16 1207 {
Chris@16 1208 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
Chris@16 1209 }
Chris@16 1210 *result = mpfr_get_sj(val.data(), GMP_RNDZ);
Chris@16 1211 }
Chris@16 1212 #endif
Chris@16 1213 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1214 inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
Chris@16 1215 {
Chris@16 1216 *result = mpfr_get_d(val.data(), GMP_RNDN);
Chris@16 1217 }
Chris@16 1218 template <unsigned digits10, mpfr_allocation_type AllocationType>
Chris@16 1219 inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
Chris@16 1220 {
Chris@16 1221 *result = mpfr_get_ld(val.data(), GMP_RNDN);
Chris@16 1222 }
Chris@16 1223
Chris@16 1224 //
Chris@16 1225 // Native non-member operations:
Chris@16 1226 //
Chris@16 1227 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1228 inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
Chris@16 1229 {
Chris@16 1230 mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
Chris@16 1231 }
Chris@16 1232
Chris@16 1233 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1234 inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
Chris@16 1235 {
Chris@16 1236 mpfr_abs(result.data(), val.data(), GMP_RNDN);
Chris@16 1237 }
Chris@16 1238
Chris@16 1239 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1240 inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
Chris@16 1241 {
Chris@16 1242 mpfr_abs(result.data(), val.data(), GMP_RNDN);
Chris@16 1243 }
Chris@16 1244 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1245 inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
Chris@16 1246 {
Chris@16 1247 mpfr_ceil(result.data(), val.data());
Chris@16 1248 }
Chris@16 1249 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1250 inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
Chris@16 1251 {
Chris@16 1252 mpfr_floor(result.data(), val.data());
Chris@16 1253 }
Chris@16 1254 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1255 inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
Chris@16 1256 {
Chris@16 1257 if(0 == mpfr_number_p(val.data()))
Chris@16 1258 {
Chris@16 1259 result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<mpfr_float_backend<Digits10, AllocateType> >(val), number<mpfr_float_backend<Digits10, AllocateType> >(val), boost::math::policies::policy<>()).backend();
Chris@16 1260 return;
Chris@16 1261 }
Chris@16 1262 mpfr_trunc(result.data(), val.data());
Chris@16 1263 }
Chris@16 1264 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1265 inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
Chris@16 1266 {
Chris@16 1267 if(e > 0)
Chris@16 1268 mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN);
Chris@16 1269 else if(e < 0)
Chris@16 1270 mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN);
Chris@16 1271 else
Chris@16 1272 result = val;
Chris@16 1273 }
Chris@16 1274 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1275 inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
Chris@16 1276 {
Chris@16 1277 long v;
Chris@16 1278 mpfr_get_d_2exp(&v, val.data(), GMP_RNDN);
Chris@16 1279 *e = v;
Chris@16 1280 eval_ldexp(result, val, -v);
Chris@16 1281 }
Chris@16 1282 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1283 inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
Chris@16 1284 {
Chris@16 1285 mpfr_get_d_2exp(e, val.data(), GMP_RNDN);
Chris@16 1286 return eval_ldexp(result, val, -*e);
Chris@16 1287 }
Chris@16 1288
Chris@16 1289 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1290 inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) BOOST_NOEXCEPT
Chris@16 1291 {
Chris@16 1292 return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
Chris@16 1293 }
Chris@16 1294
Chris@16 1295 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1296 inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
Chris@16 1297 {
Chris@16 1298 mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
Chris@16 1299 }
Chris@16 1300
Chris@16 1301 #ifdef BOOST_MSVC
Chris@16 1302 //
Chris@16 1303 // The enable_if usage below doesn't work with msvc - but only when
Chris@16 1304 // certain other enable_if usages are defined first. It's a capricious
Chris@16 1305 // and rather annoying compiler bug in other words....
Chris@16 1306 //
Chris@16 1307 # define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10) &&
Chris@16 1308 #else
Chris@16 1309 #define BOOST_MP_ENABLE_IF_WORKAROUND
Chris@16 1310 #endif
Chris@16 1311
Chris@16 1312 template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
Chris@16 1313 inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type
Chris@16 1314 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
Chris@16 1315 {
Chris@16 1316 mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
Chris@16 1317 }
Chris@16 1318
Chris@16 1319 template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
Chris@16 1320 inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type
Chris@16 1321 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
Chris@16 1322 {
Chris@16 1323 mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
Chris@16 1324 }
Chris@16 1325
Chris@16 1326 #undef BOOST_MP_ENABLE_IF_WORKAROUND
Chris@16 1327
Chris@16 1328 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1329 inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1330 {
Chris@16 1331 mpfr_exp(result.data(), arg.data(), GMP_RNDN);
Chris@16 1332 }
Chris@16 1333
Chris@16 1334 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1335 inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1336 {
Chris@16 1337 mpfr_log(result.data(), arg.data(), GMP_RNDN);
Chris@16 1338 }
Chris@16 1339
Chris@16 1340 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1341 inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1342 {
Chris@16 1343 mpfr_log10(result.data(), arg.data(), GMP_RNDN);
Chris@16 1344 }
Chris@16 1345
Chris@16 1346 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1347 inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1348 {
Chris@16 1349 mpfr_sin(result.data(), arg.data(), GMP_RNDN);
Chris@16 1350 }
Chris@16 1351
Chris@16 1352 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1353 inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1354 {
Chris@16 1355 mpfr_cos(result.data(), arg.data(), GMP_RNDN);
Chris@16 1356 }
Chris@16 1357
Chris@16 1358 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1359 inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1360 {
Chris@16 1361 mpfr_tan(result.data(), arg.data(), GMP_RNDN);
Chris@16 1362 }
Chris@16 1363
Chris@16 1364 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1365 inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1366 {
Chris@16 1367 mpfr_asin(result.data(), arg.data(), GMP_RNDN);
Chris@16 1368 }
Chris@16 1369
Chris@16 1370 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1371 inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1372 {
Chris@16 1373 mpfr_acos(result.data(), arg.data(), GMP_RNDN);
Chris@16 1374 }
Chris@16 1375
Chris@16 1376 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1377 inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1378 {
Chris@16 1379 mpfr_atan(result.data(), arg.data(), GMP_RNDN);
Chris@16 1380 }
Chris@16 1381
Chris@16 1382 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1383 inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
Chris@16 1384 {
Chris@16 1385 mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
Chris@16 1386 }
Chris@16 1387
Chris@16 1388 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1389 inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1390 {
Chris@16 1391 mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
Chris@16 1392 }
Chris@16 1393
Chris@16 1394 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1395 inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1396 {
Chris@16 1397 mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
Chris@16 1398 }
Chris@16 1399
Chris@16 1400 template <unsigned Digits10, mpfr_allocation_type AllocateType>
Chris@16 1401 inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
Chris@16 1402 {
Chris@16 1403 mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
Chris@16 1404 }
Chris@16 1405
Chris@16 1406 } // namespace backends
Chris@16 1407
Chris@16 1408 #ifdef BOOST_NO_SFINAE_EXPR
Chris@16 1409
Chris@16 1410 namespace detail{
Chris@16 1411
Chris@16 1412 template<unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
Chris@16 1413 struct is_explicitly_convertible<backends::mpfr_float_backend<D1, A1>, backends::mpfr_float_backend<D2, A2> > : public mpl::true_ {};
Chris@16 1414
Chris@16 1415 }
Chris@16 1416
Chris@16 1417 #endif
Chris@16 1418
Chris@16 1419 template<>
Chris@16 1420 struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
Chris@16 1421
Chris@16 1422 using boost::multiprecision::backends::mpfr_float_backend;
Chris@16 1423
Chris@16 1424 typedef number<mpfr_float_backend<50> > mpfr_float_50;
Chris@16 1425 typedef number<mpfr_float_backend<100> > mpfr_float_100;
Chris@16 1426 typedef number<mpfr_float_backend<500> > mpfr_float_500;
Chris@16 1427 typedef number<mpfr_float_backend<1000> > mpfr_float_1000;
Chris@16 1428 typedef number<mpfr_float_backend<0> > mpfr_float;
Chris@16 1429
Chris@16 1430 typedef number<mpfr_float_backend<50, allocate_stack> > static_mpfr_float_50;
Chris@16 1431 typedef number<mpfr_float_backend<100, allocate_stack> > static_mpfr_float_100;
Chris@16 1432
Chris@16 1433 } // namespace multiprecision
Chris@16 1434
Chris@16 1435 namespace math{
Chris@16 1436
Chris@16 1437 namespace tools{
Chris@16 1438
Chris@16 1439 template <>
Chris@16 1440 inline int digits<boost::multiprecision::mpfr_float>()
Chris@16 1441 {
Chris@16 1442 return boost::multiprecision::backends::detail::get_default_precision();
Chris@16 1443 }
Chris@16 1444 template <>
Chris@16 1445 inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
Chris@16 1446 {
Chris@16 1447 return boost::multiprecision::backends::detail::get_default_precision();
Chris@16 1448 }
Chris@16 1449
Chris@16 1450 } // namespace tools
Chris@16 1451
Chris@16 1452 namespace constants{ namespace detail{
Chris@16 1453
Chris@16 1454 template <class T> struct constant_pi;
Chris@16 1455 template <class T> struct constant_ln_two;
Chris@16 1456 template <class T> struct constant_euler;
Chris@16 1457 template <class T> struct constant_catalan;
Chris@16 1458
Chris@16 1459 namespace detail{
Chris@16 1460
Chris@16 1461 template <class T, int N>
Chris@16 1462 struct mpfr_constant_initializer
Chris@16 1463 {
Chris@16 1464 static void force_instantiate()
Chris@16 1465 {
Chris@16 1466 init.force_instantiate();
Chris@16 1467 }
Chris@16 1468 private:
Chris@16 1469 struct initializer
Chris@16 1470 {
Chris@16 1471 initializer()
Chris@16 1472 {
Chris@16 1473 T::get(mpl::int_<N>());
Chris@16 1474 }
Chris@16 1475 void force_instantiate()const{}
Chris@16 1476 };
Chris@16 1477 static const initializer init;
Chris@16 1478 };
Chris@16 1479
Chris@16 1480 template <class T, int N>
Chris@16 1481 typename mpfr_constant_initializer<T, N>::initializer const mpfr_constant_initializer<T, N>::init;
Chris@16 1482
Chris@16 1483 }
Chris@16 1484
Chris@16 1485 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1486 struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
Chris@16 1487 {
Chris@16 1488 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
Chris@16 1489 template<int N>
Chris@16 1490 static inline const result_type& get(const mpl::int_<N>&)
Chris@16 1491 {
Chris@16 1492 detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
Chris@16 1493 static result_type result;
Chris@16 1494 static bool has_init = false;
Chris@16 1495 if(!has_init)
Chris@16 1496 {
Chris@16 1497 mpfr_const_pi(result.backend().data(), GMP_RNDN);
Chris@16 1498 has_init = true;
Chris@16 1499 }
Chris@16 1500 return result;
Chris@16 1501 }
Chris@16 1502 };
Chris@16 1503 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1504 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
Chris@16 1505 {
Chris@16 1506 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
Chris@16 1507 template<int N>
Chris@16 1508 static inline const result_type& get(const mpl::int_<N>&)
Chris@16 1509 {
Chris@16 1510 detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
Chris@16 1511 static result_type result;
Chris@16 1512 static bool init = false;
Chris@16 1513 if(!init)
Chris@16 1514 {
Chris@16 1515 mpfr_const_log2(result.backend().data(), GMP_RNDN);
Chris@16 1516 init = true;
Chris@16 1517 }
Chris@16 1518 return result;
Chris@16 1519 }
Chris@16 1520 };
Chris@16 1521 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1522 struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
Chris@16 1523 {
Chris@16 1524 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
Chris@16 1525 template<int N>
Chris@16 1526 static inline const result_type& get(const mpl::int_<N>&)
Chris@16 1527 {
Chris@16 1528 detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
Chris@16 1529 static result_type result;
Chris@16 1530 static bool init = false;
Chris@16 1531 if(!init)
Chris@16 1532 {
Chris@16 1533 mpfr_const_euler(result.backend().data(), GMP_RNDN);
Chris@16 1534 init = true;
Chris@16 1535 }
Chris@16 1536 return result;
Chris@16 1537 }
Chris@16 1538 };
Chris@16 1539 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1540 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
Chris@16 1541 {
Chris@16 1542 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
Chris@16 1543 template<int N>
Chris@16 1544 static inline const result_type& get(const mpl::int_<N>&)
Chris@16 1545 {
Chris@16 1546 detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
Chris@16 1547 static result_type result;
Chris@16 1548 static bool init = false;
Chris@16 1549 if(!init)
Chris@16 1550 {
Chris@16 1551 mpfr_const_catalan(result.backend().data(), GMP_RNDN);
Chris@16 1552 init = true;
Chris@16 1553 }
Chris@16 1554 return result;
Chris@16 1555 }
Chris@16 1556 };
Chris@16 1557
Chris@16 1558 }} // namespaces
Chris@16 1559
Chris@16 1560 }} // namespaces
Chris@16 1561
Chris@16 1562 namespace std{
Chris@16 1563
Chris@16 1564 //
Chris@16 1565 // numeric_limits [partial] specializations for the types declared in this header:
Chris@16 1566 //
Chris@16 1567 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1568 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
Chris@16 1569 {
Chris@16 1570 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> number_type;
Chris@16 1571 public:
Chris@16 1572 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
Chris@16 1573 static number_type (min)()
Chris@16 1574 {
Chris@16 1575 initializer.do_nothing();
Chris@16 1576 static std::pair<bool, number_type> value;
Chris@16 1577 if(!value.first)
Chris@16 1578 {
Chris@16 1579 value.first = true;
Chris@16 1580 value.second = 0.5;
Chris@16 1581 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin(), GMP_RNDN);
Chris@16 1582 }
Chris@16 1583 return value.second;
Chris@16 1584 }
Chris@16 1585 static number_type (max)()
Chris@16 1586 {
Chris@16 1587 initializer.do_nothing();
Chris@16 1588 static std::pair<bool, number_type> value;
Chris@16 1589 if(!value.first)
Chris@16 1590 {
Chris@16 1591 value.first = true;
Chris@16 1592 value.second = 0.5;
Chris@16 1593 mpfr_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax(), GMP_RNDN);
Chris@16 1594 }
Chris@16 1595 return value.second;
Chris@16 1596 }
Chris@16 1597 BOOST_STATIC_CONSTEXPR number_type lowest()
Chris@16 1598 {
Chris@16 1599 return -(max)();
Chris@16 1600 }
Chris@16 1601 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
Chris@16 1602 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
Chris@16 1603 // Is this really correct???
Chris@16 1604 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2;
Chris@16 1605 BOOST_STATIC_CONSTEXPR bool is_signed = true;
Chris@16 1606 BOOST_STATIC_CONSTEXPR bool is_integer = false;
Chris@16 1607 BOOST_STATIC_CONSTEXPR bool is_exact = false;
Chris@16 1608 BOOST_STATIC_CONSTEXPR int radix = 2;
Chris@16 1609 static number_type epsilon()
Chris@16 1610 {
Chris@16 1611 initializer.do_nothing();
Chris@16 1612 static std::pair<bool, number_type> value;
Chris@16 1613 if(!value.first)
Chris@16 1614 {
Chris@16 1615 value.first = true;
Chris@16 1616 value.second = 1;
Chris@16 1617 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
Chris@16 1618 }
Chris@16 1619 return value.second;
Chris@16 1620 }
Chris@16 1621 // What value should this be????
Chris@16 1622 static number_type round_error()
Chris@16 1623 {
Chris@16 1624 // returns epsilon/2
Chris@16 1625 initializer.do_nothing();
Chris@16 1626 static std::pair<bool, number_type> value;
Chris@16 1627 if(!value.first)
Chris@16 1628 {
Chris@16 1629 value.first = true;
Chris@16 1630 value.second = 1;
Chris@16 1631 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), 1, GMP_RNDN);
Chris@16 1632 }
Chris@16 1633 return value.second;
Chris@16 1634 }
Chris@16 1635 BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
Chris@16 1636 BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
Chris@16 1637 BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
Chris@16 1638 BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
Chris@16 1639 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
Chris@16 1640 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
Chris@16 1641 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
Chris@16 1642 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
Chris@16 1643 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
Chris@16 1644 static number_type infinity()
Chris@16 1645 {
Chris@16 1646 // returns epsilon/2
Chris@16 1647 initializer.do_nothing();
Chris@16 1648 static std::pair<bool, number_type> value;
Chris@16 1649 if(!value.first)
Chris@16 1650 {
Chris@16 1651 value.first = true;
Chris@16 1652 value.second = 1;
Chris@16 1653 mpfr_set_inf(value.second.backend().data(), 1);
Chris@16 1654 }
Chris@16 1655 return value.second;
Chris@16 1656 }
Chris@16 1657 static number_type quiet_NaN()
Chris@16 1658 {
Chris@16 1659 // returns epsilon/2
Chris@16 1660 initializer.do_nothing();
Chris@16 1661 static std::pair<bool, number_type> value;
Chris@16 1662 if(!value.first)
Chris@16 1663 {
Chris@16 1664 value.first = true;
Chris@16 1665 value.second = 1;
Chris@16 1666 mpfr_set_nan(value.second.backend().data());
Chris@16 1667 }
Chris@16 1668 return value.second;
Chris@16 1669 }
Chris@16 1670 BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
Chris@16 1671 {
Chris@16 1672 return number_type(0);
Chris@16 1673 }
Chris@16 1674 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
Chris@16 1675 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
Chris@16 1676 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
Chris@16 1677 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
Chris@16 1678 BOOST_STATIC_CONSTEXPR bool traps = true;
Chris@16 1679 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
Chris@16 1680 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
Chris@16 1681
Chris@16 1682 private:
Chris@16 1683 struct data_initializer
Chris@16 1684 {
Chris@16 1685 data_initializer()
Chris@16 1686 {
Chris@16 1687 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::epsilon();
Chris@16 1688 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::round_error();
Chris@16 1689 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::min)();
Chris@16 1690 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::max)();
Chris@16 1691 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::infinity();
Chris@16 1692 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::quiet_NaN();
Chris@16 1693 }
Chris@16 1694 void do_nothing()const{}
Chris@16 1695 };
Chris@16 1696 static const data_initializer initializer;
Chris@16 1697 };
Chris@16 1698
Chris@16 1699 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1700 const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::initializer;
Chris@16 1701
Chris@16 1702 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
Chris@16 1703
Chris@16 1704 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1705 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
Chris@16 1706 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1707 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
Chris@16 1708 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1709 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
Chris@16 1710 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1711 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
Chris@16 1712 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1713 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
Chris@16 1714 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1715 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
Chris@16 1716 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1717 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
Chris@16 1718 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1719 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
Chris@16 1720 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1721 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
Chris@16 1722 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1723 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
Chris@16 1724 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1725 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
Chris@16 1726 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1727 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
Chris@16 1728 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1729 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
Chris@16 1730 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1731 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
Chris@16 1732 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1733 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
Chris@16 1734 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1735 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
Chris@16 1736 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1737 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
Chris@16 1738 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1739 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
Chris@16 1740 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1741 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
Chris@16 1742 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1743 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
Chris@16 1744 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1745 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
Chris@16 1746 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1747 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
Chris@16 1748
Chris@16 1749 #endif
Chris@16 1750
Chris@16 1751
Chris@16 1752 template<boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1753 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
Chris@16 1754 {
Chris@16 1755 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> number_type;
Chris@16 1756 public:
Chris@16 1757 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
Chris@16 1758 static number_type (min)() { return number_type(0); }
Chris@16 1759 static number_type (max)() { return number_type(0); }
Chris@16 1760 static number_type lowest() { return number_type(0); }
Chris@16 1761 BOOST_STATIC_CONSTEXPR int digits = 0;
Chris@16 1762 BOOST_STATIC_CONSTEXPR int digits10 = 0;
Chris@16 1763 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
Chris@16 1764 BOOST_STATIC_CONSTEXPR bool is_signed = false;
Chris@16 1765 BOOST_STATIC_CONSTEXPR bool is_integer = false;
Chris@16 1766 BOOST_STATIC_CONSTEXPR bool is_exact = false;
Chris@16 1767 BOOST_STATIC_CONSTEXPR int radix = 0;
Chris@16 1768 static number_type epsilon() { return number_type(0); }
Chris@16 1769 static number_type round_error() { return number_type(0); }
Chris@16 1770 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
Chris@16 1771 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
Chris@16 1772 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
Chris@16 1773 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
Chris@16 1774 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
Chris@16 1775 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
Chris@16 1776 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
Chris@16 1777 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
Chris@16 1778 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
Chris@16 1779 static number_type infinity() { return number_type(0); }
Chris@16 1780 static number_type quiet_NaN() { return number_type(0); }
Chris@16 1781 static number_type signaling_NaN() { return number_type(0); }
Chris@16 1782 static number_type denorm_min() { return number_type(0); }
Chris@16 1783 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
Chris@16 1784 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
Chris@16 1785 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
Chris@16 1786 BOOST_STATIC_CONSTEXPR bool traps = false;
Chris@16 1787 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
Chris@16 1788 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
Chris@16 1789 };
Chris@16 1790
Chris@16 1791 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
Chris@16 1792
Chris@16 1793 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1794 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
Chris@16 1795 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1796 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
Chris@16 1797 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1798 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
Chris@16 1799 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1800 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
Chris@16 1801 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1802 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
Chris@16 1803 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1804 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
Chris@16 1805 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1806 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
Chris@16 1807 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1808 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
Chris@16 1809 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1810 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
Chris@16 1811 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1812 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
Chris@16 1813 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1814 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
Chris@16 1815 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1816 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
Chris@16 1817 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1818 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
Chris@16 1819 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1820 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
Chris@16 1821 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1822 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
Chris@16 1823 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1824 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
Chris@16 1825 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1826 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
Chris@16 1827 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1828 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
Chris@16 1829 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1830 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
Chris@16 1831 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1832 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
Chris@16 1833 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1834 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
Chris@16 1835 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1836 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;
Chris@16 1837
Chris@16 1838 #endif
Chris@16 1839 } // namespace std
Chris@16 1840 #endif