annotate DEPENDENCIES/generic/include/boost/multiprecision/gmp.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_ER_GMP_BACKEND_HPP
Chris@16 7 #define BOOST_MATH_ER_GMP_BACKEND_HPP
Chris@16 8
Chris@16 9 #include <boost/multiprecision/number.hpp>
Chris@16 10 #include <boost/multiprecision/detail/integer_ops.hpp>
Chris@16 11 #include <boost/multiprecision/detail/big_lanczos.hpp>
Chris@16 12 #include <boost/multiprecision/detail/digits.hpp>
Chris@16 13 #include <boost/math/special_functions/fpclassify.hpp>
Chris@16 14 #include <boost/cstdint.hpp>
Chris@16 15 #ifdef BOOST_MSVC
Chris@16 16 # pragma warning(push)
Chris@16 17 # pragma warning(disable:4127)
Chris@16 18 #endif
Chris@16 19 #include <gmp.h>
Chris@16 20 #ifdef BOOST_MSVC
Chris@16 21 # pragma warning(pop)
Chris@16 22 #endif
Chris@16 23 #include <cmath>
Chris@16 24 #include <limits>
Chris@16 25 #include <climits>
Chris@16 26
Chris@16 27 namespace boost{
Chris@16 28 namespace multiprecision{
Chris@16 29 namespace backends{
Chris@16 30
Chris@16 31 #ifdef BOOST_MSVC
Chris@16 32 // warning C4127: conditional expression is constant
Chris@16 33 #pragma warning(push)
Chris@16 34 #pragma warning(disable:4127)
Chris@16 35 #endif
Chris@16 36
Chris@16 37 template <unsigned digits10>
Chris@16 38 struct gmp_float;
Chris@16 39 struct gmp_int;
Chris@16 40 struct gmp_rational;
Chris@16 41
Chris@16 42 } // namespace backends
Chris@16 43
Chris@16 44 template<>
Chris@16 45 struct number_category<backends::gmp_int> : public mpl::int_<number_kind_integer>{};
Chris@16 46 template<>
Chris@16 47 struct number_category<backends::gmp_rational> : public mpl::int_<number_kind_rational>{};
Chris@16 48 template <unsigned digits10>
Chris@16 49 struct number_category<backends::gmp_float<digits10> > : public mpl::int_<number_kind_floating_point>{};
Chris@16 50
Chris@16 51 namespace backends{
Chris@16 52 //
Chris@16 53 // Within this file, the only functions we mark as noexcept are those that manipulate
Chris@16 54 // (but don't create) an mpf_t. All other types may allocate at pretty much any time
Chris@16 55 // via a user-supplied allocator, and therefore throw.
Chris@16 56 //
Chris@16 57 namespace detail{
Chris@16 58
Chris@16 59 template <unsigned digits10>
Chris@16 60 struct gmp_float_imp
Chris@16 61 {
Chris@16 62 typedef mpl::list<long, long long> signed_types;
Chris@16 63 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
Chris@16 64 typedef mpl::list<double, long double> float_types;
Chris@16 65 typedef long exponent_type;
Chris@16 66
Chris@16 67 gmp_float_imp() BOOST_NOEXCEPT {}
Chris@16 68
Chris@16 69 gmp_float_imp(const gmp_float_imp& o)
Chris@16 70 {
Chris@16 71 //
Chris@16 72 // We have to do an init followed by a set here, otherwise *this may be at
Chris@16 73 // a lower precision than o: seems like mpf_init_set copies just enough bits
Chris@16 74 // to get the right value, but if it's then used in further calculations
Chris@16 75 // things go badly wrong!!
Chris@16 76 //
Chris@16 77 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 78 if(o.m_data[0]._mp_d)
Chris@16 79 mpf_set(m_data, o.m_data);
Chris@16 80 }
Chris@16 81 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 82 gmp_float_imp(gmp_float_imp&& o) BOOST_NOEXCEPT
Chris@16 83 {
Chris@16 84 m_data[0] = o.m_data[0];
Chris@16 85 o.m_data[0]._mp_d = 0;
Chris@16 86 }
Chris@16 87 #endif
Chris@16 88 gmp_float_imp& operator = (const gmp_float_imp& o)
Chris@16 89 {
Chris@16 90 if(m_data[0]._mp_d == 0)
Chris@16 91 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 92 if(o.m_data[0]._mp_d)
Chris@16 93 mpf_set(m_data, o.m_data);
Chris@16 94 return *this;
Chris@16 95 }
Chris@16 96 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 97 gmp_float_imp& operator = (gmp_float_imp&& o) BOOST_NOEXCEPT
Chris@16 98 {
Chris@16 99 mpf_swap(m_data, o.m_data);
Chris@16 100 return *this;
Chris@16 101 }
Chris@16 102 #endif
Chris@16 103 gmp_float_imp& operator = (unsigned long long i)
Chris@16 104 {
Chris@16 105 if(m_data[0]._mp_d == 0)
Chris@16 106 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 107 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
Chris@16 108 unsigned shift = 0;
Chris@16 109 mpf_t t;
Chris@16 110 mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 111 mpf_set_ui(m_data, 0);
Chris@16 112 while(i)
Chris@16 113 {
Chris@16 114 mpf_set_ui(t, static_cast<unsigned>(i & mask));
Chris@16 115 if(shift)
Chris@16 116 mpf_mul_2exp(t, t, shift);
Chris@16 117 mpf_add(m_data, m_data, t);
Chris@16 118 shift += std::numeric_limits<unsigned>::digits;
Chris@16 119 i >>= std::numeric_limits<unsigned>::digits;
Chris@16 120 }
Chris@16 121 mpf_clear(t);
Chris@16 122 return *this;
Chris@16 123 }
Chris@16 124 gmp_float_imp& operator = (long long i)
Chris@16 125 {
Chris@16 126 if(m_data[0]._mp_d == 0)
Chris@16 127 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 128 bool neg = i < 0;
Chris@101 129 *this = static_cast<unsigned long long>(boost::multiprecision::detail::unsigned_abs(i));
Chris@16 130 if(neg)
Chris@16 131 mpf_neg(m_data, m_data);
Chris@16 132 return *this;
Chris@16 133 }
Chris@16 134 gmp_float_imp& operator = (unsigned long i)
Chris@16 135 {
Chris@16 136 if(m_data[0]._mp_d == 0)
Chris@16 137 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 138 mpf_set_ui(m_data, i);
Chris@16 139 return *this;
Chris@16 140 }
Chris@16 141 gmp_float_imp& operator = (long i)
Chris@16 142 {
Chris@16 143 if(m_data[0]._mp_d == 0)
Chris@16 144 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 145 mpf_set_si(m_data, i);
Chris@16 146 return *this;
Chris@16 147 }
Chris@16 148 gmp_float_imp& operator = (double d)
Chris@16 149 {
Chris@16 150 if(m_data[0]._mp_d == 0)
Chris@16 151 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 152 mpf_set_d(m_data, d);
Chris@16 153 return *this;
Chris@16 154 }
Chris@16 155 gmp_float_imp& operator = (long double a)
Chris@16 156 {
Chris@16 157 using std::frexp;
Chris@16 158 using std::ldexp;
Chris@16 159 using std::floor;
Chris@16 160
Chris@16 161 if(m_data[0]._mp_d == 0)
Chris@16 162 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 163
Chris@16 164 if (a == 0) {
Chris@16 165 mpf_set_si(m_data, 0);
Chris@16 166 return *this;
Chris@16 167 }
Chris@16 168
Chris@16 169 if (a == 1) {
Chris@16 170 mpf_set_si(m_data, 1);
Chris@16 171 return *this;
Chris@16 172 }
Chris@16 173
Chris@16 174 BOOST_ASSERT(!(boost::math::isinf)(a));
Chris@16 175 BOOST_ASSERT(!(boost::math::isnan)(a));
Chris@16 176
Chris@16 177 int e;
Chris@16 178 long double f, term;
Chris@16 179 mpf_set_ui(m_data, 0u);
Chris@16 180
Chris@16 181 f = frexp(a, &e);
Chris@16 182
Chris@16 183 static const int shift = std::numeric_limits<int>::digits - 1;
Chris@16 184
Chris@16 185 while(f)
Chris@16 186 {
Chris@16 187 // extract int sized bits from f:
Chris@16 188 f = ldexp(f, shift);
Chris@16 189 term = floor(f);
Chris@16 190 e -= shift;
Chris@16 191 mpf_mul_2exp(m_data, m_data, shift);
Chris@16 192 if(term > 0)
Chris@16 193 mpf_add_ui(m_data, m_data, static_cast<unsigned>(term));
Chris@16 194 else
Chris@16 195 mpf_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
Chris@16 196 f -= term;
Chris@16 197 }
Chris@16 198 if(e > 0)
Chris@16 199 mpf_mul_2exp(m_data, m_data, e);
Chris@16 200 else if(e < 0)
Chris@16 201 mpf_div_2exp(m_data, m_data, -e);
Chris@16 202 return *this;
Chris@16 203 }
Chris@16 204 gmp_float_imp& operator = (const char* s)
Chris@16 205 {
Chris@16 206 if(m_data[0]._mp_d == 0)
Chris@16 207 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 208 if(0 != mpf_set_str(m_data, s, 10))
Chris@16 209 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid floating point number.")));
Chris@16 210 return *this;
Chris@16 211 }
Chris@16 212 void swap(gmp_float_imp& o) BOOST_NOEXCEPT
Chris@16 213 {
Chris@16 214 mpf_swap(m_data, o.m_data);
Chris@16 215 }
Chris@16 216 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
Chris@16 217 {
Chris@16 218 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 219
Chris@16 220 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
Chris@16 221 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
Chris@16 222 std::streamsize org_digits(digits);
Chris@16 223
Chris@16 224 if(scientific && digits)
Chris@16 225 ++digits;
Chris@16 226
Chris@16 227 std::string result;
Chris@16 228 mp_exp_t e;
Chris@16 229 void *(*alloc_func_ptr) (size_t);
Chris@16 230 void *(*realloc_func_ptr) (void *, size_t, size_t);
Chris@16 231 void (*free_func_ptr) (void *, size_t);
Chris@16 232 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
Chris@16 233
Chris@16 234 if(mpf_sgn(m_data) == 0)
Chris@16 235 {
Chris@16 236 e = 0;
Chris@16 237 result = "0";
Chris@16 238 if(fixed && digits)
Chris@16 239 ++digits;
Chris@16 240 }
Chris@16 241 else
Chris@16 242 {
Chris@16 243 char* ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
Chris@16 244 --e; // To match with what our formatter expects.
Chris@16 245 if(fixed && e != -1)
Chris@16 246 {
Chris@16 247 // Oops we actually need a different number of digits to what we asked for:
Chris@16 248 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
Chris@16 249 digits += e + 1;
Chris@16 250 if(digits == 0)
Chris@16 251 {
Chris@16 252 // We need to get *all* the digits and then possibly round up,
Chris@16 253 // we end up with either "0" or "1" as the result.
Chris@16 254 ps = mpf_get_str (0, &e, 10, 0, m_data);
Chris@16 255 --e;
Chris@16 256 unsigned offset = *ps == '-' ? 1 : 0;
Chris@16 257 if(ps[offset] > '5')
Chris@16 258 {
Chris@16 259 ++e;
Chris@16 260 ps[offset] = '1';
Chris@16 261 ps[offset + 1] = 0;
Chris@16 262 }
Chris@16 263 else if(ps[offset] == '5')
Chris@16 264 {
Chris@16 265 unsigned i = offset + 1;
Chris@16 266 bool round_up = false;
Chris@16 267 while(ps[i] != 0)
Chris@16 268 {
Chris@16 269 if(ps[i] != '0')
Chris@16 270 {
Chris@16 271 round_up = true;
Chris@16 272 break;
Chris@16 273 }
Chris@16 274 }
Chris@16 275 if(round_up)
Chris@16 276 {
Chris@16 277 ++e;
Chris@16 278 ps[offset] = '1';
Chris@16 279 ps[offset + 1] = 0;
Chris@16 280 }
Chris@16 281 else
Chris@16 282 {
Chris@16 283 ps[offset] = '0';
Chris@16 284 ps[offset + 1] = 0;
Chris@16 285 }
Chris@16 286 }
Chris@16 287 else
Chris@16 288 {
Chris@16 289 ps[offset] = '0';
Chris@16 290 ps[offset + 1] = 0;
Chris@16 291 }
Chris@16 292 }
Chris@16 293 else if(digits > 0)
Chris@16 294 {
Chris@16 295 ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
Chris@16 296 --e; // To match with what our formatter expects.
Chris@16 297 }
Chris@16 298 else
Chris@16 299 {
Chris@16 300 ps = mpf_get_str (0, &e, 10, 1, m_data);
Chris@16 301 --e;
Chris@16 302 unsigned offset = *ps == '-' ? 1 : 0;
Chris@16 303 ps[offset] = '0';
Chris@16 304 ps[offset + 1] = 0;
Chris@16 305 }
Chris@16 306 }
Chris@16 307 result = ps;
Chris@16 308 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
Chris@16 309 }
Chris@16 310 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, mpf_sgn(m_data) == 0);
Chris@16 311 return result;
Chris@16 312 }
Chris@16 313 ~gmp_float_imp() BOOST_NOEXCEPT
Chris@16 314 {
Chris@16 315 if(m_data[0]._mp_d)
Chris@16 316 mpf_clear(m_data);
Chris@16 317 }
Chris@16 318 void negate() BOOST_NOEXCEPT
Chris@16 319 {
Chris@16 320 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 321 mpf_neg(m_data, m_data);
Chris@16 322 }
Chris@16 323 int compare(const gmp_float<digits10>& o)const BOOST_NOEXCEPT
Chris@16 324 {
Chris@16 325 BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
Chris@16 326 return mpf_cmp(m_data, o.m_data);
Chris@16 327 }
Chris@16 328 int compare(long i)const BOOST_NOEXCEPT
Chris@16 329 {
Chris@16 330 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 331 return mpf_cmp_si(m_data, i);
Chris@16 332 }
Chris@16 333 int compare(unsigned long i)const BOOST_NOEXCEPT
Chris@16 334 {
Chris@16 335 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 336 return mpf_cmp_ui(m_data, i);
Chris@16 337 }
Chris@16 338 template <class V>
Chris@16 339 typename enable_if<is_arithmetic<V>, int>::type compare(V v)const
Chris@16 340 {
Chris@16 341 gmp_float<digits10> d;
Chris@16 342 d = v;
Chris@16 343 return compare(d);
Chris@16 344 }
Chris@16 345 mpf_t& data() BOOST_NOEXCEPT
Chris@16 346 {
Chris@16 347 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 348 return m_data;
Chris@16 349 }
Chris@16 350 const mpf_t& data()const BOOST_NOEXCEPT
Chris@16 351 {
Chris@16 352 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 353 return m_data;
Chris@16 354 }
Chris@16 355 protected:
Chris@16 356 mpf_t m_data;
Chris@16 357 static unsigned& get_default_precision() BOOST_NOEXCEPT
Chris@16 358 {
Chris@16 359 static unsigned val = 50;
Chris@16 360 return val;
Chris@16 361 }
Chris@16 362 };
Chris@16 363
Chris@16 364 } // namespace detail
Chris@16 365
Chris@16 366 struct gmp_int;
Chris@16 367 struct gmp_rational;
Chris@16 368
Chris@16 369 template <unsigned digits10>
Chris@16 370 struct gmp_float : public detail::gmp_float_imp<digits10>
Chris@16 371 {
Chris@16 372 gmp_float()
Chris@16 373 {
Chris@16 374 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 375 }
Chris@16 376 gmp_float(const gmp_float& o) : detail::gmp_float_imp<digits10>(o) {}
Chris@16 377 template <unsigned D>
Chris@16 378 gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= digits10>::type* = 0);
Chris@16 379 template <unsigned D>
Chris@16 380 explicit gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= digits10>::type* = 0);
Chris@16 381 gmp_float(const gmp_int& o);
Chris@16 382 gmp_float(const gmp_rational& o);
Chris@16 383 gmp_float(const mpf_t val)
Chris@16 384 {
Chris@16 385 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 386 mpf_set(this->m_data, val);
Chris@16 387 }
Chris@16 388 gmp_float(const mpz_t val)
Chris@16 389 {
Chris@16 390 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 391 mpf_set_z(this->m_data, val);
Chris@16 392 }
Chris@16 393 gmp_float(const mpq_t val)
Chris@16 394 {
Chris@16 395 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 396 mpf_set_q(this->m_data, val);
Chris@16 397 }
Chris@16 398 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 399 gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<digits10>(static_cast<detail::gmp_float_imp<digits10>&&>(o)) {}
Chris@16 400 #endif
Chris@16 401 gmp_float& operator=(const gmp_float& o)
Chris@16 402 {
Chris@16 403 *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10> const&>(o);
Chris@16 404 return *this;
Chris@16 405 }
Chris@16 406 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 407 gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT
Chris@16 408 {
Chris@16 409 *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10>&&>(o);
Chris@16 410 return *this;
Chris@16 411 }
Chris@16 412 #endif
Chris@16 413 template <unsigned D>
Chris@16 414 gmp_float& operator=(const gmp_float<D>& o);
Chris@16 415 gmp_float& operator=(const gmp_int& o);
Chris@16 416 gmp_float& operator=(const gmp_rational& o);
Chris@16 417 gmp_float& operator=(const mpf_t val)
Chris@16 418 {
Chris@16 419 if(this->m_data[0]._mp_d == 0)
Chris@16 420 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 421 mpf_set(this->m_data, val);
Chris@16 422 return *this;
Chris@16 423 }
Chris@16 424 gmp_float& operator=(const mpz_t val)
Chris@16 425 {
Chris@16 426 if(this->m_data[0]._mp_d == 0)
Chris@16 427 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 428 mpf_set_z(this->m_data, val);
Chris@16 429 return *this;
Chris@16 430 }
Chris@16 431 gmp_float& operator=(const mpq_t val)
Chris@16 432 {
Chris@16 433 if(this->m_data[0]._mp_d == 0)
Chris@16 434 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 435 mpf_set_q(this->m_data, val);
Chris@16 436 return *this;
Chris@16 437 }
Chris@16 438 template <class V>
Chris@16 439 gmp_float& operator=(const V& v)
Chris@16 440 {
Chris@16 441 *static_cast<detail::gmp_float_imp<digits10>*>(this) = v;
Chris@16 442 return *this;
Chris@16 443 }
Chris@16 444 };
Chris@16 445
Chris@16 446 template <>
Chris@16 447 struct gmp_float<0> : public detail::gmp_float_imp<0>
Chris@16 448 {
Chris@16 449 gmp_float()
Chris@16 450 {
Chris@16 451 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 452 }
Chris@16 453 gmp_float(const mpf_t val)
Chris@16 454 {
Chris@16 455 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 456 mpf_set(this->m_data, val);
Chris@16 457 }
Chris@16 458 gmp_float(const mpz_t val)
Chris@16 459 {
Chris@16 460 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 461 mpf_set_z(this->m_data, val);
Chris@16 462 }
Chris@16 463 gmp_float(const mpq_t val)
Chris@16 464 {
Chris@16 465 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 466 mpf_set_q(this->m_data, val);
Chris@16 467 }
Chris@16 468 gmp_float(const gmp_float& o) : detail::gmp_float_imp<0>(o) {}
Chris@16 469 template <unsigned D>
Chris@16 470 gmp_float(const gmp_float<D>& o)
Chris@16 471 {
Chris@16 472 mpf_init2(this->m_data, mpf_get_prec(o.data()));
Chris@16 473 mpf_set(this->m_data, o.data());
Chris@16 474 }
Chris@16 475 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 476 gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<0>(static_cast<detail::gmp_float_imp<0>&&>(o)) {}
Chris@16 477 #endif
Chris@16 478 gmp_float(const gmp_int& o);
Chris@16 479 gmp_float(const gmp_rational& o);
Chris@16 480 gmp_float(const gmp_float& o, unsigned digits10)
Chris@16 481 {
Chris@16 482 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 483 mpf_set(this->m_data, o.data());
Chris@16 484 }
Chris@16 485
Chris@16 486 gmp_float& operator=(const gmp_float& o)
Chris@16 487 {
Chris@16 488 *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> const&>(o);
Chris@16 489 return *this;
Chris@16 490 }
Chris@16 491 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 492 gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT
Chris@16 493 {
Chris@16 494 *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> &&>(o);
Chris@16 495 return *this;
Chris@16 496 }
Chris@16 497 #endif
Chris@16 498 template <unsigned D>
Chris@16 499 gmp_float& operator=(const gmp_float<D>& o)
Chris@16 500 {
Chris@16 501 if(this->m_data[0]._mp_d == 0)
Chris@16 502 {
Chris@16 503 mpf_init2(this->m_data, mpf_get_prec(o.data()));
Chris@16 504 }
Chris@16 505 else
Chris@16 506 {
Chris@16 507 mpf_set_prec(this->m_data, mpf_get_prec(o.data()));
Chris@16 508 }
Chris@16 509 mpf_set(this->m_data, o.data());
Chris@16 510 return *this;
Chris@16 511 }
Chris@16 512 gmp_float& operator=(const gmp_int& o);
Chris@16 513 gmp_float& operator=(const gmp_rational& o);
Chris@16 514 gmp_float& operator=(const mpf_t val)
Chris@16 515 {
Chris@16 516 if(this->m_data[0]._mp_d == 0)
Chris@16 517 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 518 mpf_set(this->m_data, val);
Chris@16 519 return *this;
Chris@16 520 }
Chris@16 521 gmp_float& operator=(const mpz_t val)
Chris@16 522 {
Chris@16 523 if(this->m_data[0]._mp_d == 0)
Chris@16 524 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 525 mpf_set_z(this->m_data, val);
Chris@16 526 return *this;
Chris@16 527 }
Chris@16 528 gmp_float& operator=(const mpq_t val)
Chris@16 529 {
Chris@16 530 if(this->m_data[0]._mp_d == 0)
Chris@16 531 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 532 mpf_set_q(this->m_data, val);
Chris@16 533 return *this;
Chris@16 534 }
Chris@16 535 template <class V>
Chris@16 536 gmp_float& operator=(const V& v)
Chris@16 537 {
Chris@16 538 *static_cast<detail::gmp_float_imp<0>*>(this) = v;
Chris@16 539 return *this;
Chris@16 540 }
Chris@16 541 static unsigned default_precision() BOOST_NOEXCEPT
Chris@16 542 {
Chris@16 543 return get_default_precision();
Chris@16 544 }
Chris@16 545 static void default_precision(unsigned v) BOOST_NOEXCEPT
Chris@16 546 {
Chris@16 547 get_default_precision() = v;
Chris@16 548 }
Chris@16 549 unsigned precision()const BOOST_NOEXCEPT
Chris@16 550 {
Chris@16 551 return multiprecision::detail::digits2_2_10(mpf_get_prec(this->m_data));
Chris@16 552 }
Chris@16 553 void precision(unsigned digits10) BOOST_NOEXCEPT
Chris@16 554 {
Chris@16 555 mpf_set_prec(this->m_data, multiprecision::detail::digits10_2_2(digits10));
Chris@16 556 }
Chris@16 557 };
Chris@16 558
Chris@16 559 template <unsigned digits10, class T>
Chris@16 560 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_eq(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
Chris@16 561 {
Chris@16 562 return a.compare(b) == 0;
Chris@16 563 }
Chris@16 564 template <unsigned digits10, class T>
Chris@16 565 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_lt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
Chris@16 566 {
Chris@16 567 return a.compare(b) < 0;
Chris@16 568 }
Chris@16 569 template <unsigned digits10, class T>
Chris@16 570 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_gt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
Chris@16 571 {
Chris@16 572 return a.compare(b) > 0;
Chris@16 573 }
Chris@16 574
Chris@16 575 template <unsigned D1, unsigned D2>
Chris@16 576 inline void eval_add(gmp_float<D1>& result, const gmp_float<D2>& o)
Chris@16 577 {
Chris@16 578 mpf_add(result.data(), result.data(), o.data());
Chris@16 579 }
Chris@16 580 template <unsigned D1, unsigned D2>
Chris@16 581 inline void eval_subtract(gmp_float<D1>& result, const gmp_float<D2>& o)
Chris@16 582 {
Chris@16 583 mpf_sub(result.data(), result.data(), o.data());
Chris@16 584 }
Chris@16 585 template <unsigned D1, unsigned D2>
Chris@16 586 inline void eval_multiply(gmp_float<D1>& result, const gmp_float<D2>& o)
Chris@16 587 {
Chris@16 588 mpf_mul(result.data(), result.data(), o.data());
Chris@16 589 }
Chris@16 590 template <unsigned digits10>
Chris@16 591 inline bool eval_is_zero(const gmp_float<digits10>& val) BOOST_NOEXCEPT
Chris@16 592 {
Chris@16 593 return mpf_sgn(val.data()) == 0;
Chris@16 594 }
Chris@16 595 template <unsigned D1, unsigned D2>
Chris@16 596 inline void eval_divide(gmp_float<D1>& result, const gmp_float<D2>& o)
Chris@16 597 {
Chris@16 598 if(eval_is_zero(o))
Chris@16 599 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 600 mpf_div(result.data(), result.data(), o.data());
Chris@16 601 }
Chris@16 602 template <unsigned digits10>
Chris@16 603 inline void eval_add(gmp_float<digits10>& result, unsigned long i)
Chris@16 604 {
Chris@16 605 mpf_add_ui(result.data(), result.data(), i);
Chris@16 606 }
Chris@16 607 template <unsigned digits10>
Chris@16 608 inline void eval_subtract(gmp_float<digits10>& result, unsigned long i)
Chris@16 609 {
Chris@16 610 mpf_sub_ui(result.data(), result.data(), i);
Chris@16 611 }
Chris@16 612 template <unsigned digits10>
Chris@16 613 inline void eval_multiply(gmp_float<digits10>& result, unsigned long i)
Chris@16 614 {
Chris@16 615 mpf_mul_ui(result.data(), result.data(), i);
Chris@16 616 }
Chris@16 617 template <unsigned digits10>
Chris@16 618 inline void eval_divide(gmp_float<digits10>& result, unsigned long i)
Chris@16 619 {
Chris@16 620 if(i == 0)
Chris@16 621 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 622 mpf_div_ui(result.data(), result.data(), i);
Chris@16 623 }
Chris@16 624 template <unsigned digits10>
Chris@16 625 inline void eval_add(gmp_float<digits10>& result, long i)
Chris@16 626 {
Chris@16 627 if(i > 0)
Chris@16 628 mpf_add_ui(result.data(), result.data(), i);
Chris@16 629 else
Chris@16 630 mpf_sub_ui(result.data(), result.data(), std::abs(i));
Chris@16 631 }
Chris@16 632 template <unsigned digits10>
Chris@16 633 inline void eval_subtract(gmp_float<digits10>& result, long i)
Chris@16 634 {
Chris@16 635 if(i > 0)
Chris@16 636 mpf_sub_ui(result.data(), result.data(), i);
Chris@16 637 else
Chris@16 638 mpf_add_ui(result.data(), result.data(), std::abs(i));
Chris@16 639 }
Chris@16 640 template <unsigned digits10>
Chris@16 641 inline void eval_multiply(gmp_float<digits10>& result, long i)
Chris@16 642 {
Chris@16 643 mpf_mul_ui(result.data(), result.data(), std::abs(i));
Chris@16 644 if(i < 0)
Chris@16 645 mpf_neg(result.data(), result.data());
Chris@16 646 }
Chris@16 647 template <unsigned digits10>
Chris@16 648 inline void eval_divide(gmp_float<digits10>& result, long i)
Chris@16 649 {
Chris@16 650 if(i == 0)
Chris@16 651 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 652 mpf_div_ui(result.data(), result.data(), std::abs(i));
Chris@16 653 if(i < 0)
Chris@16 654 mpf_neg(result.data(), result.data());
Chris@16 655 }
Chris@16 656 //
Chris@16 657 // Specialised 3 arg versions of the basic operators:
Chris@16 658 //
Chris@16 659 template <unsigned D1, unsigned D2, unsigned D3>
Chris@16 660 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
Chris@16 661 {
Chris@16 662 mpf_add(a.data(), x.data(), y.data());
Chris@16 663 }
Chris@16 664 template <unsigned D1, unsigned D2>
Chris@16 665 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
Chris@16 666 {
Chris@16 667 mpf_add_ui(a.data(), x.data(), y);
Chris@16 668 }
Chris@16 669 template <unsigned D1, unsigned D2>
Chris@16 670 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
Chris@16 671 {
Chris@16 672 if(y < 0)
Chris@101 673 mpf_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
Chris@16 674 else
Chris@16 675 mpf_add_ui(a.data(), x.data(), y);
Chris@16 676 }
Chris@16 677 template <unsigned D1, unsigned D2>
Chris@16 678 inline void eval_add(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
Chris@16 679 {
Chris@16 680 mpf_add_ui(a.data(), y.data(), x);
Chris@16 681 }
Chris@16 682 template <unsigned D1, unsigned D2>
Chris@16 683 inline void eval_add(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
Chris@16 684 {
Chris@16 685 if(x < 0)
Chris@16 686 {
Chris@101 687 mpf_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
Chris@16 688 mpf_neg(a.data(), a.data());
Chris@16 689 }
Chris@16 690 else
Chris@16 691 mpf_add_ui(a.data(), y.data(), x);
Chris@16 692 }
Chris@16 693 template <unsigned D1, unsigned D2, unsigned D3>
Chris@16 694 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
Chris@16 695 {
Chris@16 696 mpf_sub(a.data(), x.data(), y.data());
Chris@16 697 }
Chris@16 698 template <unsigned D1, unsigned D2>
Chris@16 699 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
Chris@16 700 {
Chris@16 701 mpf_sub_ui(a.data(), x.data(), y);
Chris@16 702 }
Chris@16 703 template <unsigned D1, unsigned D2>
Chris@16 704 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
Chris@16 705 {
Chris@16 706 if(y < 0)
Chris@101 707 mpf_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
Chris@16 708 else
Chris@16 709 mpf_sub_ui(a.data(), x.data(), y);
Chris@16 710 }
Chris@16 711 template <unsigned D1, unsigned D2>
Chris@16 712 inline void eval_subtract(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
Chris@16 713 {
Chris@16 714 mpf_ui_sub(a.data(), x, y.data());
Chris@16 715 }
Chris@16 716 template <unsigned D1, unsigned D2>
Chris@16 717 inline void eval_subtract(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
Chris@16 718 {
Chris@16 719 if(x < 0)
Chris@16 720 {
Chris@101 721 mpf_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
Chris@16 722 mpf_neg(a.data(), a.data());
Chris@16 723 }
Chris@16 724 else
Chris@16 725 mpf_ui_sub(a.data(), x, y.data());
Chris@16 726 }
Chris@16 727
Chris@16 728 template <unsigned D1, unsigned D2, unsigned D3>
Chris@16 729 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
Chris@16 730 {
Chris@16 731 mpf_mul(a.data(), x.data(), y.data());
Chris@16 732 }
Chris@16 733 template <unsigned D1, unsigned D2>
Chris@16 734 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
Chris@16 735 {
Chris@16 736 mpf_mul_ui(a.data(), x.data(), y);
Chris@16 737 }
Chris@16 738 template <unsigned D1, unsigned D2>
Chris@16 739 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
Chris@16 740 {
Chris@16 741 if(y < 0)
Chris@16 742 {
Chris@101 743 mpf_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
Chris@16 744 a.negate();
Chris@16 745 }
Chris@16 746 else
Chris@16 747 mpf_mul_ui(a.data(), x.data(), y);
Chris@16 748 }
Chris@16 749 template <unsigned D1, unsigned D2>
Chris@16 750 inline void eval_multiply(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
Chris@16 751 {
Chris@16 752 mpf_mul_ui(a.data(), y.data(), x);
Chris@16 753 }
Chris@16 754 template <unsigned D1, unsigned D2>
Chris@16 755 inline void eval_multiply(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
Chris@16 756 {
Chris@16 757 if(x < 0)
Chris@16 758 {
Chris@101 759 mpf_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
Chris@16 760 mpf_neg(a.data(), a.data());
Chris@16 761 }
Chris@16 762 else
Chris@16 763 mpf_mul_ui(a.data(), y.data(), x);
Chris@16 764 }
Chris@16 765
Chris@16 766 template <unsigned D1, unsigned D2, unsigned D3>
Chris@16 767 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
Chris@16 768 {
Chris@16 769 if(eval_is_zero(y))
Chris@16 770 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 771 mpf_div(a.data(), x.data(), y.data());
Chris@16 772 }
Chris@16 773 template <unsigned D1, unsigned D2>
Chris@16 774 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
Chris@16 775 {
Chris@16 776 if(y == 0)
Chris@16 777 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 778 mpf_div_ui(a.data(), x.data(), y);
Chris@16 779 }
Chris@16 780 template <unsigned D1, unsigned D2>
Chris@16 781 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
Chris@16 782 {
Chris@16 783 if(y == 0)
Chris@16 784 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 785 if(y < 0)
Chris@16 786 {
Chris@101 787 mpf_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
Chris@16 788 a.negate();
Chris@16 789 }
Chris@16 790 else
Chris@16 791 mpf_div_ui(a.data(), x.data(), y);
Chris@16 792 }
Chris@16 793 template <unsigned D1, unsigned D2>
Chris@16 794 inline void eval_divide(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
Chris@16 795 {
Chris@16 796 if(eval_is_zero(y))
Chris@16 797 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 798 mpf_ui_div(a.data(), x, y.data());
Chris@16 799 }
Chris@16 800 template <unsigned D1, unsigned D2>
Chris@16 801 inline void eval_divide(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
Chris@16 802 {
Chris@16 803 if(eval_is_zero(y))
Chris@16 804 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 805 if(x < 0)
Chris@16 806 {
Chris@101 807 mpf_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
Chris@16 808 mpf_neg(a.data(), a.data());
Chris@16 809 }
Chris@16 810 else
Chris@16 811 mpf_ui_div(a.data(), x, y.data());
Chris@16 812 }
Chris@16 813
Chris@16 814 template <unsigned digits10>
Chris@16 815 inline int eval_get_sign(const gmp_float<digits10>& val) BOOST_NOEXCEPT
Chris@16 816 {
Chris@16 817 return mpf_sgn(val.data());
Chris@16 818 }
Chris@16 819
Chris@16 820 template <unsigned digits10>
Chris@16 821 inline void eval_convert_to(unsigned long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
Chris@16 822 {
Chris@16 823 if(0 == mpf_fits_ulong_p(val.data()))
Chris@16 824 *result = (std::numeric_limits<unsigned long>::max)();
Chris@16 825 else
Chris@16 826 *result = mpf_get_ui(val.data());
Chris@16 827 }
Chris@16 828 template <unsigned digits10>
Chris@16 829 inline void eval_convert_to(long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
Chris@16 830 {
Chris@16 831 if(0 == mpf_fits_slong_p(val.data()))
Chris@16 832 {
Chris@16 833 *result = (std::numeric_limits<unsigned long>::max)();
Chris@16 834 *result *= mpf_sgn(val.data());
Chris@16 835 }
Chris@16 836 else
Chris@16 837 *result = mpf_get_si(val.data());
Chris@16 838 }
Chris@16 839 template <unsigned digits10>
Chris@16 840 inline void eval_convert_to(double* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
Chris@16 841 {
Chris@16 842 *result = mpf_get_d(val.data());
Chris@16 843 }
Chris@16 844 #ifdef BOOST_HAS_LONG_LONG
Chris@16 845 template <unsigned digits10>
Chris@16 846 inline void eval_convert_to(long long* result, const gmp_float<digits10>& val)
Chris@16 847 {
Chris@16 848 gmp_float<digits10> t(val);
Chris@16 849 if(eval_get_sign(t) < 0)
Chris@16 850 t.negate();
Chris@16 851
Chris@16 852 long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits;
Chris@16 853
Chris@16 854 if(digits > 0)
Chris@16 855 mpf_div_2exp(t.data(), t.data(), digits);
Chris@16 856
Chris@16 857 if(!mpf_fits_slong_p(t.data()))
Chris@16 858 {
Chris@16 859 if(eval_get_sign(val) < 0)
Chris@16 860 *result = (std::numeric_limits<long long>::min)();
Chris@16 861 else
Chris@16 862 *result = (std::numeric_limits<long long>::max)();
Chris@16 863 return;
Chris@16 864 };
Chris@16 865
Chris@16 866 *result = mpf_get_si(t.data());
Chris@16 867 while(digits > 0)
Chris@16 868 {
Chris@16 869 *result <<= digits;
Chris@16 870 digits -= std::numeric_limits<unsigned long>::digits;
Chris@16 871 mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
Chris@16 872 unsigned long l = mpf_get_ui(t.data());
Chris@16 873 if(digits < 0)
Chris@16 874 l >>= -digits;
Chris@16 875 *result |= l;
Chris@16 876 }
Chris@16 877 if(eval_get_sign(val) < 0)
Chris@16 878 *result = -*result;
Chris@16 879 }
Chris@16 880 template <unsigned digits10>
Chris@16 881 inline void eval_convert_to(unsigned long long* result, const gmp_float<digits10>& val)
Chris@16 882 {
Chris@16 883 gmp_float<digits10> t(val);
Chris@16 884
Chris@16 885 long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits;
Chris@16 886
Chris@16 887 if(digits > 0)
Chris@16 888 mpf_div_2exp(t.data(), t.data(), digits);
Chris@16 889
Chris@16 890 if(!mpf_fits_ulong_p(t.data()))
Chris@16 891 {
Chris@16 892 *result = (std::numeric_limits<long long>::max)();
Chris@16 893 return;
Chris@16 894 }
Chris@16 895
Chris@16 896 *result = mpf_get_ui(t.data());
Chris@16 897 while(digits > 0)
Chris@16 898 {
Chris@16 899 *result <<= digits;
Chris@16 900 digits -= std::numeric_limits<unsigned long>::digits;
Chris@16 901 mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
Chris@16 902 unsigned long l = mpf_get_ui(t.data());
Chris@16 903 if(digits < 0)
Chris@16 904 l >>= -digits;
Chris@16 905 *result |= l;
Chris@16 906 }
Chris@16 907 }
Chris@16 908 #endif
Chris@16 909
Chris@16 910 //
Chris@16 911 // Native non-member operations:
Chris@16 912 //
Chris@16 913 template <unsigned Digits10>
Chris@16 914 inline void eval_sqrt(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
Chris@16 915 {
Chris@16 916 mpf_sqrt(result.data(), val.data());
Chris@16 917 }
Chris@16 918
Chris@16 919 template <unsigned Digits10>
Chris@16 920 inline void eval_abs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
Chris@16 921 {
Chris@16 922 mpf_abs(result.data(), val.data());
Chris@16 923 }
Chris@16 924
Chris@16 925 template <unsigned Digits10>
Chris@16 926 inline void eval_fabs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
Chris@16 927 {
Chris@16 928 mpf_abs(result.data(), val.data());
Chris@16 929 }
Chris@16 930 template <unsigned Digits10>
Chris@16 931 inline void eval_ceil(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
Chris@16 932 {
Chris@16 933 mpf_ceil(result.data(), val.data());
Chris@16 934 }
Chris@16 935 template <unsigned Digits10>
Chris@16 936 inline void eval_floor(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
Chris@16 937 {
Chris@16 938 mpf_floor(result.data(), val.data());
Chris@16 939 }
Chris@16 940 template <unsigned Digits10>
Chris@16 941 inline void eval_trunc(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
Chris@16 942 {
Chris@16 943 mpf_trunc(result.data(), val.data());
Chris@16 944 }
Chris@16 945 template <unsigned Digits10>
Chris@16 946 inline void eval_ldexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long e)
Chris@16 947 {
Chris@16 948 if(e > 0)
Chris@16 949 mpf_mul_2exp(result.data(), val.data(), e);
Chris@16 950 else if(e < 0)
Chris@16 951 mpf_div_2exp(result.data(), val.data(), -e);
Chris@16 952 else
Chris@16 953 result = val;
Chris@16 954 }
Chris@16 955 template <unsigned Digits10>
Chris@16 956 inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, int* e)
Chris@16 957 {
Chris@16 958 long v;
Chris@16 959 mpf_get_d_2exp(&v, val.data());
Chris@16 960 *e = v;
Chris@16 961 eval_ldexp(result, val, -v);
Chris@16 962 }
Chris@16 963 template <unsigned Digits10>
Chris@16 964 inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long* e)
Chris@16 965 {
Chris@16 966 mpf_get_d_2exp(e, val.data());
Chris@16 967 eval_ldexp(result, val, -*e);
Chris@16 968 }
Chris@16 969
Chris@16 970 struct gmp_int
Chris@16 971 {
Chris@16 972 typedef mpl::list<long, long long> signed_types;
Chris@16 973 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
Chris@16 974 typedef mpl::list<double, long double> float_types;
Chris@16 975
Chris@16 976 gmp_int()
Chris@16 977 {
Chris@16 978 mpz_init(this->m_data);
Chris@16 979 }
Chris@16 980 gmp_int(const gmp_int& o)
Chris@16 981 {
Chris@16 982 if(o.m_data[0]._mp_d)
Chris@16 983 mpz_init_set(m_data, o.m_data);
Chris@16 984 else
Chris@16 985 mpz_init(this->m_data);
Chris@16 986 }
Chris@16 987 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 988 gmp_int(gmp_int&& o) BOOST_NOEXCEPT
Chris@16 989 {
Chris@16 990 m_data[0] = o.m_data[0];
Chris@16 991 o.m_data[0]._mp_d = 0;
Chris@16 992 }
Chris@16 993 #endif
Chris@16 994 explicit gmp_int(const mpf_t val)
Chris@16 995 {
Chris@16 996 mpz_init(this->m_data);
Chris@16 997 mpz_set_f(this->m_data, val);
Chris@16 998 }
Chris@16 999 gmp_int(const mpz_t val)
Chris@16 1000 {
Chris@16 1001 mpz_init_set(this->m_data, val);
Chris@16 1002 }
Chris@16 1003 explicit gmp_int(const mpq_t val)
Chris@16 1004 {
Chris@16 1005 mpz_init(this->m_data);
Chris@16 1006 mpz_set_q(this->m_data, val);
Chris@16 1007 }
Chris@16 1008 template <unsigned Digits10>
Chris@16 1009 explicit gmp_int(const gmp_float<Digits10>& o)
Chris@16 1010 {
Chris@16 1011 mpz_init(this->m_data);
Chris@16 1012 mpz_set_f(this->m_data, o.data());
Chris@16 1013 }
Chris@16 1014 explicit gmp_int(const gmp_rational& o);
Chris@16 1015 gmp_int& operator = (const gmp_int& o)
Chris@16 1016 {
Chris@16 1017 if(m_data[0]._mp_d == 0)
Chris@16 1018 mpz_init(this->m_data);
Chris@16 1019 mpz_set(m_data, o.m_data);
Chris@16 1020 return *this;
Chris@16 1021 }
Chris@16 1022 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 1023 gmp_int& operator = (gmp_int&& o) BOOST_NOEXCEPT
Chris@16 1024 {
Chris@16 1025 mpz_swap(m_data, o.m_data);
Chris@16 1026 return *this;
Chris@16 1027 }
Chris@16 1028 #endif
Chris@16 1029 gmp_int& operator = (unsigned long long i)
Chris@16 1030 {
Chris@16 1031 if(m_data[0]._mp_d == 0)
Chris@16 1032 mpz_init(this->m_data);
Chris@16 1033 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
Chris@16 1034 unsigned shift = 0;
Chris@16 1035 mpz_t t;
Chris@16 1036 mpz_set_ui(m_data, 0);
Chris@16 1037 mpz_init_set_ui(t, 0);
Chris@16 1038 while(i)
Chris@16 1039 {
Chris@16 1040 mpz_set_ui(t, static_cast<unsigned>(i & mask));
Chris@16 1041 if(shift)
Chris@16 1042 mpz_mul_2exp(t, t, shift);
Chris@16 1043 mpz_add(m_data, m_data, t);
Chris@16 1044 shift += std::numeric_limits<unsigned>::digits;
Chris@16 1045 i >>= std::numeric_limits<unsigned>::digits;
Chris@16 1046 }
Chris@16 1047 mpz_clear(t);
Chris@16 1048 return *this;
Chris@16 1049 }
Chris@16 1050 gmp_int& operator = (long long i)
Chris@16 1051 {
Chris@16 1052 if(m_data[0]._mp_d == 0)
Chris@16 1053 mpz_init(this->m_data);
Chris@16 1054 bool neg = i < 0;
Chris@101 1055 *this = boost::multiprecision::detail::unsigned_abs(i);
Chris@16 1056 if(neg)
Chris@16 1057 mpz_neg(m_data, m_data);
Chris@16 1058 return *this;
Chris@16 1059 }
Chris@16 1060 gmp_int& operator = (unsigned long i)
Chris@16 1061 {
Chris@16 1062 if(m_data[0]._mp_d == 0)
Chris@16 1063 mpz_init(this->m_data);
Chris@16 1064 mpz_set_ui(m_data, i);
Chris@16 1065 return *this;
Chris@16 1066 }
Chris@16 1067 gmp_int& operator = (long i)
Chris@16 1068 {
Chris@16 1069 if(m_data[0]._mp_d == 0)
Chris@16 1070 mpz_init(this->m_data);
Chris@16 1071 mpz_set_si(m_data, i);
Chris@16 1072 return *this;
Chris@16 1073 }
Chris@16 1074 gmp_int& operator = (double d)
Chris@16 1075 {
Chris@16 1076 if(m_data[0]._mp_d == 0)
Chris@16 1077 mpz_init(this->m_data);
Chris@16 1078 mpz_set_d(m_data, d);
Chris@16 1079 return *this;
Chris@16 1080 }
Chris@16 1081 gmp_int& operator = (long double a)
Chris@16 1082 {
Chris@16 1083 using std::frexp;
Chris@16 1084 using std::ldexp;
Chris@16 1085 using std::floor;
Chris@16 1086
Chris@16 1087 if(m_data[0]._mp_d == 0)
Chris@16 1088 mpz_init(this->m_data);
Chris@16 1089
Chris@16 1090 if (a == 0) {
Chris@16 1091 mpz_set_si(m_data, 0);
Chris@16 1092 return *this;
Chris@16 1093 }
Chris@16 1094
Chris@16 1095 if (a == 1) {
Chris@16 1096 mpz_set_si(m_data, 1);
Chris@16 1097 return *this;
Chris@16 1098 }
Chris@16 1099
Chris@16 1100 BOOST_ASSERT(!(boost::math::isinf)(a));
Chris@16 1101 BOOST_ASSERT(!(boost::math::isnan)(a));
Chris@16 1102
Chris@16 1103 int e;
Chris@16 1104 long double f, term;
Chris@16 1105 mpz_set_ui(m_data, 0u);
Chris@16 1106
Chris@16 1107 f = frexp(a, &e);
Chris@16 1108
Chris@16 1109 static const int shift = std::numeric_limits<int>::digits - 1;
Chris@16 1110
Chris@16 1111 while(f)
Chris@16 1112 {
Chris@16 1113 // extract int sized bits from f:
Chris@16 1114 f = ldexp(f, shift);
Chris@16 1115 term = floor(f);
Chris@16 1116 e -= shift;
Chris@16 1117 mpz_mul_2exp(m_data, m_data, shift);
Chris@16 1118 if(term > 0)
Chris@16 1119 mpz_add_ui(m_data, m_data, static_cast<unsigned>(term));
Chris@16 1120 else
Chris@16 1121 mpz_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
Chris@16 1122 f -= term;
Chris@16 1123 }
Chris@16 1124 if(e > 0)
Chris@16 1125 mpz_mul_2exp(m_data, m_data, e);
Chris@16 1126 else if(e < 0)
Chris@16 1127 mpz_div_2exp(m_data, m_data, -e);
Chris@16 1128 return *this;
Chris@16 1129 }
Chris@16 1130 gmp_int& operator = (const char* s)
Chris@16 1131 {
Chris@16 1132 if(m_data[0]._mp_d == 0)
Chris@16 1133 mpz_init(this->m_data);
Chris@16 1134 std::size_t n = s ? std::strlen(s) : 0;
Chris@16 1135 int radix = 10;
Chris@16 1136 if(n && (*s == '0'))
Chris@16 1137 {
Chris@16 1138 if((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
Chris@16 1139 {
Chris@16 1140 radix = 16;
Chris@16 1141 s +=2;
Chris@16 1142 n -= 2;
Chris@16 1143 }
Chris@16 1144 else
Chris@16 1145 {
Chris@16 1146 radix = 8;
Chris@16 1147 n -= 1;
Chris@16 1148 }
Chris@16 1149 }
Chris@16 1150 if(n)
Chris@16 1151 {
Chris@16 1152 if(0 != mpz_set_str(m_data, s, radix))
Chris@16 1153 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid integer.")));
Chris@16 1154 }
Chris@16 1155 else
Chris@16 1156 mpz_set_ui(m_data, 0);
Chris@16 1157 return *this;
Chris@16 1158 }
Chris@16 1159 gmp_int& operator=(const mpf_t val)
Chris@16 1160 {
Chris@16 1161 if(m_data[0]._mp_d == 0)
Chris@16 1162 mpz_init(this->m_data);
Chris@16 1163 mpz_set_f(this->m_data, val);
Chris@16 1164 return *this;
Chris@16 1165 }
Chris@16 1166 gmp_int& operator=(const mpz_t val)
Chris@16 1167 {
Chris@16 1168 if(m_data[0]._mp_d == 0)
Chris@16 1169 mpz_init(this->m_data);
Chris@16 1170 mpz_set(this->m_data, val);
Chris@16 1171 return *this;
Chris@16 1172 }
Chris@16 1173 gmp_int& operator=(const mpq_t val)
Chris@16 1174 {
Chris@16 1175 if(m_data[0]._mp_d == 0)
Chris@16 1176 mpz_init(this->m_data);
Chris@16 1177 mpz_set_q(this->m_data, val);
Chris@16 1178 return *this;
Chris@16 1179 }
Chris@16 1180 template <unsigned Digits10>
Chris@16 1181 gmp_int& operator=(const gmp_float<Digits10>& o)
Chris@16 1182 {
Chris@16 1183 if(m_data[0]._mp_d == 0)
Chris@16 1184 mpz_init(this->m_data);
Chris@16 1185 mpz_set_f(this->m_data, o.data());
Chris@16 1186 return *this;
Chris@16 1187 }
Chris@16 1188 gmp_int& operator=(const gmp_rational& o);
Chris@16 1189 void swap(gmp_int& o)
Chris@16 1190 {
Chris@16 1191 mpz_swap(m_data, o.m_data);
Chris@16 1192 }
Chris@16 1193 std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
Chris@16 1194 {
Chris@16 1195 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 1196
Chris@16 1197 int base = 10;
Chris@16 1198 if((f & std::ios_base::oct) == std::ios_base::oct)
Chris@16 1199 base = 8;
Chris@16 1200 else if((f & std::ios_base::hex) == std::ios_base::hex)
Chris@16 1201 base = 16;
Chris@16 1202 //
Chris@16 1203 // sanity check, bases 8 and 16 are only available for positive numbers:
Chris@16 1204 //
Chris@16 1205 if((base != 10) && (mpz_sgn(m_data) < 0))
Chris@16 1206 BOOST_THROW_EXCEPTION(std::runtime_error("Formatted output in bases 8 or 16 is only available for positive numbers"));
Chris@16 1207 void *(*alloc_func_ptr) (size_t);
Chris@16 1208 void *(*realloc_func_ptr) (void *, size_t, size_t);
Chris@16 1209 void (*free_func_ptr) (void *, size_t);
Chris@16 1210 const char* ps = mpz_get_str (0, base, m_data);
Chris@16 1211 std::string s = ps;
Chris@16 1212 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
Chris@16 1213 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
Chris@16 1214
Chris@16 1215 if((base != 10) && (f & std::ios_base::showbase))
Chris@16 1216 {
Chris@16 1217 int pos = s[0] == '-' ? 1 : 0;
Chris@16 1218 const char* pp = base == 8 ? "0" : "0x";
Chris@101 1219 s.insert(static_cast<std::string::size_type>(pos), pp);
Chris@16 1220 }
Chris@16 1221 if((f & std::ios_base::showpos) && (s[0] != '-'))
Chris@101 1222 s.insert(static_cast<std::string::size_type>(0), 1, '+');
Chris@16 1223
Chris@16 1224 return s;
Chris@16 1225 }
Chris@16 1226 ~gmp_int() BOOST_NOEXCEPT
Chris@16 1227 {
Chris@16 1228 if(m_data[0]._mp_d)
Chris@16 1229 mpz_clear(m_data);
Chris@16 1230 }
Chris@16 1231 void negate() BOOST_NOEXCEPT
Chris@16 1232 {
Chris@16 1233 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 1234 mpz_neg(m_data, m_data);
Chris@16 1235 }
Chris@16 1236 int compare(const gmp_int& o)const BOOST_NOEXCEPT
Chris@16 1237 {
Chris@16 1238 BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
Chris@16 1239 return mpz_cmp(m_data, o.m_data);
Chris@16 1240 }
Chris@16 1241 int compare(long i)const BOOST_NOEXCEPT
Chris@16 1242 {
Chris@16 1243 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 1244 return mpz_cmp_si(m_data, i);
Chris@16 1245 }
Chris@16 1246 int compare(unsigned long i)const BOOST_NOEXCEPT
Chris@16 1247 {
Chris@16 1248 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 1249 return mpz_cmp_ui(m_data, i);
Chris@16 1250 }
Chris@16 1251 template <class V>
Chris@16 1252 int compare(V v)const
Chris@16 1253 {
Chris@16 1254 gmp_int d;
Chris@16 1255 d = v;
Chris@16 1256 return compare(d);
Chris@16 1257 }
Chris@16 1258 mpz_t& data() BOOST_NOEXCEPT
Chris@16 1259 {
Chris@16 1260 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 1261 return m_data;
Chris@16 1262 }
Chris@16 1263 const mpz_t& data()const BOOST_NOEXCEPT
Chris@16 1264 {
Chris@16 1265 BOOST_ASSERT(m_data[0]._mp_d);
Chris@16 1266 return m_data;
Chris@16 1267 }
Chris@16 1268 protected:
Chris@16 1269 mpz_t m_data;
Chris@16 1270 };
Chris@16 1271
Chris@16 1272 template <class T>
Chris@16 1273 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const gmp_int& a, const T& b)
Chris@16 1274 {
Chris@16 1275 return a.compare(b) == 0;
Chris@16 1276 }
Chris@16 1277 template <class T>
Chris@16 1278 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const gmp_int& a, const T& b)
Chris@16 1279 {
Chris@16 1280 return a.compare(b) < 0;
Chris@16 1281 }
Chris@16 1282 template <class T>
Chris@16 1283 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const gmp_int& a, const T& b)
Chris@16 1284 {
Chris@16 1285 return a.compare(b) > 0;
Chris@16 1286 }
Chris@16 1287
Chris@16 1288 inline bool eval_is_zero(const gmp_int& val)
Chris@16 1289 {
Chris@16 1290 return mpz_sgn(val.data()) == 0;
Chris@16 1291 }
Chris@16 1292 inline void eval_add(gmp_int& t, const gmp_int& o)
Chris@16 1293 {
Chris@16 1294 mpz_add(t.data(), t.data(), o.data());
Chris@16 1295 }
Chris@16 1296 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, const gmp_int& b)
Chris@16 1297 {
Chris@16 1298 mpz_addmul(t.data(), a.data(), b.data());
Chris@16 1299 }
Chris@16 1300 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, const gmp_int& b)
Chris@16 1301 {
Chris@16 1302 mpz_submul(t.data(), a.data(), b.data());
Chris@16 1303 }
Chris@16 1304 inline void eval_subtract(gmp_int& t, const gmp_int& o)
Chris@16 1305 {
Chris@16 1306 mpz_sub(t.data(), t.data(), o.data());
Chris@16 1307 }
Chris@16 1308 inline void eval_multiply(gmp_int& t, const gmp_int& o)
Chris@16 1309 {
Chris@16 1310 mpz_mul(t.data(), t.data(), o.data());
Chris@16 1311 }
Chris@16 1312 inline void eval_divide(gmp_int& t, const gmp_int& o)
Chris@16 1313 {
Chris@16 1314 if(eval_is_zero(o))
Chris@16 1315 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 1316 mpz_tdiv_q(t.data(), t.data(), o.data());
Chris@16 1317 }
Chris@16 1318 inline void eval_modulus(gmp_int& t, const gmp_int& o)
Chris@16 1319 {
Chris@16 1320 mpz_tdiv_r(t.data(), t.data(), o.data());
Chris@16 1321 }
Chris@16 1322 inline void eval_add(gmp_int& t, unsigned long i)
Chris@16 1323 {
Chris@16 1324 mpz_add_ui(t.data(), t.data(), i);
Chris@16 1325 }
Chris@16 1326 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, unsigned long i)
Chris@16 1327 {
Chris@16 1328 mpz_addmul_ui(t.data(), a.data(), i);
Chris@16 1329 }
Chris@16 1330 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, unsigned long i)
Chris@16 1331 {
Chris@16 1332 mpz_submul_ui(t.data(), a.data(), i);
Chris@16 1333 }
Chris@16 1334 inline void eval_subtract(gmp_int& t, unsigned long i)
Chris@16 1335 {
Chris@16 1336 mpz_sub_ui(t.data(), t.data(), i);
Chris@16 1337 }
Chris@16 1338 inline void eval_multiply(gmp_int& t, unsigned long i)
Chris@16 1339 {
Chris@16 1340 mpz_mul_ui(t.data(), t.data(), i);
Chris@16 1341 }
Chris@16 1342 inline void eval_modulus(gmp_int& t, unsigned long i)
Chris@16 1343 {
Chris@16 1344 mpz_tdiv_r_ui(t.data(), t.data(), i);
Chris@16 1345 }
Chris@16 1346 inline void eval_divide(gmp_int& t, unsigned long i)
Chris@16 1347 {
Chris@16 1348 if(i == 0)
Chris@16 1349 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 1350 mpz_tdiv_q_ui(t.data(), t.data(), i);
Chris@16 1351 }
Chris@16 1352 inline void eval_add(gmp_int& t, long i)
Chris@16 1353 {
Chris@16 1354 if(i > 0)
Chris@16 1355 mpz_add_ui(t.data(), t.data(), i);
Chris@16 1356 else
Chris@101 1357 mpz_sub_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 1358 }
Chris@16 1359 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, long i)
Chris@16 1360 {
Chris@16 1361 if(i > 0)
Chris@16 1362 mpz_addmul_ui(t.data(), a.data(), i);
Chris@16 1363 else
Chris@101 1364 mpz_submul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 1365 }
Chris@16 1366 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, long i)
Chris@16 1367 {
Chris@16 1368 if(i > 0)
Chris@16 1369 mpz_submul_ui(t.data(), a.data(), i);
Chris@16 1370 else
Chris@101 1371 mpz_addmul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 1372 }
Chris@16 1373 inline void eval_subtract(gmp_int& t, long i)
Chris@16 1374 {
Chris@16 1375 if(i > 0)
Chris@16 1376 mpz_sub_ui(t.data(), t.data(), i);
Chris@16 1377 else
Chris@101 1378 mpz_add_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 1379 }
Chris@16 1380 inline void eval_multiply(gmp_int& t, long i)
Chris@16 1381 {
Chris@16 1382 mpz_mul_ui(t.data(), t.data(), std::abs(i));
Chris@16 1383 if(i < 0)
Chris@16 1384 mpz_neg(t.data(), t.data());
Chris@16 1385 }
Chris@16 1386 inline void eval_modulus(gmp_int& t, long i)
Chris@16 1387 {
Chris@16 1388 mpz_tdiv_r_ui(t.data(), t.data(), std::abs(i));
Chris@16 1389 }
Chris@16 1390 inline void eval_divide(gmp_int& t, long i)
Chris@16 1391 {
Chris@16 1392 if(i == 0)
Chris@16 1393 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 1394 mpz_tdiv_q_ui(t.data(), t.data(), std::abs(i));
Chris@16 1395 if(i < 0)
Chris@16 1396 mpz_neg(t.data(), t.data());
Chris@16 1397 }
Chris@16 1398 template <class UI>
Chris@16 1399 inline void eval_left_shift(gmp_int& t, UI i)
Chris@16 1400 {
Chris@16 1401 mpz_mul_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
Chris@16 1402 }
Chris@16 1403 template <class UI>
Chris@16 1404 inline void eval_right_shift(gmp_int& t, UI i)
Chris@16 1405 {
Chris@16 1406 mpz_fdiv_q_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
Chris@16 1407 }
Chris@16 1408 template <class UI>
Chris@16 1409 inline void eval_left_shift(gmp_int& t, const gmp_int& v, UI i)
Chris@16 1410 {
Chris@16 1411 mpz_mul_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
Chris@16 1412 }
Chris@16 1413 template <class UI>
Chris@16 1414 inline void eval_right_shift(gmp_int& t, const gmp_int& v, UI i)
Chris@16 1415 {
Chris@16 1416 mpz_fdiv_q_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
Chris@16 1417 }
Chris@16 1418
Chris@16 1419 inline void eval_bitwise_and(gmp_int& result, const gmp_int& v)
Chris@16 1420 {
Chris@16 1421 mpz_and(result.data(), result.data(), v.data());
Chris@16 1422 }
Chris@16 1423
Chris@16 1424 inline void eval_bitwise_or(gmp_int& result, const gmp_int& v)
Chris@16 1425 {
Chris@16 1426 mpz_ior(result.data(), result.data(), v.data());
Chris@16 1427 }
Chris@16 1428
Chris@16 1429 inline void eval_bitwise_xor(gmp_int& result, const gmp_int& v)
Chris@16 1430 {
Chris@16 1431 mpz_xor(result.data(), result.data(), v.data());
Chris@16 1432 }
Chris@16 1433
Chris@16 1434 inline void eval_add(gmp_int& t, const gmp_int& p, const gmp_int& o)
Chris@16 1435 {
Chris@16 1436 mpz_add(t.data(), p.data(), o.data());
Chris@16 1437 }
Chris@16 1438 inline void eval_subtract(gmp_int& t, const gmp_int& p, const gmp_int& o)
Chris@16 1439 {
Chris@16 1440 mpz_sub(t.data(), p.data(), o.data());
Chris@16 1441 }
Chris@16 1442 inline void eval_multiply(gmp_int& t, const gmp_int& p, const gmp_int& o)
Chris@16 1443 {
Chris@16 1444 mpz_mul(t.data(), p.data(), o.data());
Chris@16 1445 }
Chris@16 1446 inline void eval_divide(gmp_int& t, const gmp_int& p, const gmp_int& o)
Chris@16 1447 {
Chris@16 1448 if(eval_is_zero(o))
Chris@16 1449 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 1450 mpz_tdiv_q(t.data(), p.data(), o.data());
Chris@16 1451 }
Chris@16 1452 inline void eval_modulus(gmp_int& t, const gmp_int& p, const gmp_int& o)
Chris@16 1453 {
Chris@16 1454 mpz_tdiv_r(t.data(), p.data(), o.data());
Chris@16 1455 }
Chris@16 1456 inline void eval_add(gmp_int& t, const gmp_int& p, unsigned long i)
Chris@16 1457 {
Chris@16 1458 mpz_add_ui(t.data(), p.data(), i);
Chris@16 1459 }
Chris@16 1460 inline void eval_subtract(gmp_int& t, const gmp_int& p, unsigned long i)
Chris@16 1461 {
Chris@16 1462 mpz_sub_ui(t.data(), p.data(), i);
Chris@16 1463 }
Chris@16 1464 inline void eval_multiply(gmp_int& t, const gmp_int& p, unsigned long i)
Chris@16 1465 {
Chris@16 1466 mpz_mul_ui(t.data(), p.data(), i);
Chris@16 1467 }
Chris@16 1468 inline void eval_modulus(gmp_int& t, const gmp_int& p, unsigned long i)
Chris@16 1469 {
Chris@16 1470 mpz_tdiv_r_ui(t.data(), p.data(), i);
Chris@16 1471 }
Chris@16 1472 inline void eval_divide(gmp_int& t, const gmp_int& p, unsigned long i)
Chris@16 1473 {
Chris@16 1474 if(i == 0)
Chris@16 1475 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 1476 mpz_tdiv_q_ui(t.data(), p.data(), i);
Chris@16 1477 }
Chris@16 1478 inline void eval_add(gmp_int& t, const gmp_int& p, long i)
Chris@16 1479 {
Chris@16 1480 if(i > 0)
Chris@16 1481 mpz_add_ui(t.data(), p.data(), i);
Chris@16 1482 else
Chris@101 1483 mpz_sub_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 1484 }
Chris@16 1485 inline void eval_subtract(gmp_int& t, const gmp_int& p, long i)
Chris@16 1486 {
Chris@16 1487 if(i > 0)
Chris@16 1488 mpz_sub_ui(t.data(), p.data(), i);
Chris@16 1489 else
Chris@101 1490 mpz_add_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 1491 }
Chris@16 1492 inline void eval_multiply(gmp_int& t, const gmp_int& p, long i)
Chris@16 1493 {
Chris@16 1494 mpz_mul_ui(t.data(), p.data(), std::abs(i));
Chris@16 1495 if(i < 0)
Chris@16 1496 mpz_neg(t.data(), t.data());
Chris@16 1497 }
Chris@16 1498 inline void eval_modulus(gmp_int& t, const gmp_int& p, long i)
Chris@16 1499 {
Chris@16 1500 mpz_tdiv_r_ui(t.data(), p.data(), std::abs(i));
Chris@16 1501 }
Chris@16 1502 inline void eval_divide(gmp_int& t, const gmp_int& p, long i)
Chris@16 1503 {
Chris@16 1504 if(i == 0)
Chris@16 1505 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 1506 mpz_tdiv_q_ui(t.data(), p.data(), std::abs(i));
Chris@16 1507 if(i < 0)
Chris@16 1508 mpz_neg(t.data(), t.data());
Chris@16 1509 }
Chris@16 1510
Chris@16 1511 inline void eval_bitwise_and(gmp_int& result, const gmp_int& u, const gmp_int& v)
Chris@16 1512 {
Chris@16 1513 mpz_and(result.data(), u.data(), v.data());
Chris@16 1514 }
Chris@16 1515
Chris@16 1516 inline void eval_bitwise_or(gmp_int& result, const gmp_int& u, const gmp_int& v)
Chris@16 1517 {
Chris@16 1518 mpz_ior(result.data(), u.data(), v.data());
Chris@16 1519 }
Chris@16 1520
Chris@16 1521 inline void eval_bitwise_xor(gmp_int& result, const gmp_int& u, const gmp_int& v)
Chris@16 1522 {
Chris@16 1523 mpz_xor(result.data(), u.data(), v.data());
Chris@16 1524 }
Chris@16 1525
Chris@16 1526 inline void eval_complement(gmp_int& result, const gmp_int& u)
Chris@16 1527 {
Chris@16 1528 mpz_com(result.data(), u.data());
Chris@16 1529 }
Chris@16 1530
Chris@16 1531 inline int eval_get_sign(const gmp_int& val)
Chris@16 1532 {
Chris@16 1533 return mpz_sgn(val.data());
Chris@16 1534 }
Chris@16 1535 inline void eval_convert_to(unsigned long* result, const gmp_int& val)
Chris@16 1536 {
Chris@16 1537 if(0 == mpz_fits_ulong_p(val.data()))
Chris@16 1538 {
Chris@16 1539 *result = (std::numeric_limits<unsigned long>::max)();
Chris@16 1540 }
Chris@16 1541 else
Chris@16 1542 *result = mpz_get_ui(val.data());
Chris@16 1543 }
Chris@16 1544 inline void eval_convert_to(long* result, const gmp_int& val)
Chris@16 1545 {
Chris@16 1546 if(0 == mpz_fits_slong_p(val.data()))
Chris@16 1547 {
Chris@16 1548 *result = (std::numeric_limits<unsigned long>::max)();
Chris@16 1549 *result *= mpz_sgn(val.data());
Chris@16 1550 }
Chris@16 1551 else
Chris@16 1552 *result = mpz_get_si(val.data());
Chris@16 1553 }
Chris@16 1554 inline void eval_convert_to(double* result, const gmp_int& val)
Chris@16 1555 {
Chris@16 1556 *result = mpz_get_d(val.data());
Chris@16 1557 }
Chris@16 1558
Chris@16 1559 inline void eval_abs(gmp_int& result, const gmp_int& val)
Chris@16 1560 {
Chris@16 1561 mpz_abs(result.data(), val.data());
Chris@16 1562 }
Chris@16 1563
Chris@16 1564 inline void eval_gcd(gmp_int& result, const gmp_int& a, const gmp_int& b)
Chris@16 1565 {
Chris@16 1566 mpz_gcd(result.data(), a.data(), b.data());
Chris@16 1567 }
Chris@16 1568 inline void eval_lcm(gmp_int& result, const gmp_int& a, const gmp_int& b)
Chris@16 1569 {
Chris@16 1570 mpz_lcm(result.data(), a.data(), b.data());
Chris@16 1571 }
Chris@16 1572 template <class I>
Chris@16 1573 inline typename enable_if_c<(is_unsigned<I>::value && (sizeof(I) <= sizeof(unsigned long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b)
Chris@16 1574 {
Chris@16 1575 mpz_gcd_ui(result.data(), a.data(), b);
Chris@16 1576 }
Chris@16 1577 template <class I>
Chris@16 1578 inline typename enable_if_c<(is_unsigned<I>::value && (sizeof(I) <= sizeof(unsigned long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b)
Chris@16 1579 {
Chris@16 1580 mpz_lcm_ui(result.data(), a.data(), b);
Chris@16 1581 }
Chris@16 1582 template <class I>
Chris@16 1583 inline typename enable_if_c<(is_signed<I>::value && (sizeof(I) <= sizeof(long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b)
Chris@16 1584 {
Chris@16 1585 mpz_gcd_ui(result.data(), a.data(), std::abs(b));
Chris@16 1586 }
Chris@16 1587 template <class I>
Chris@16 1588 inline typename enable_if_c<is_signed<I>::value && ((sizeof(I) <= sizeof(long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b)
Chris@16 1589 {
Chris@16 1590 mpz_lcm_ui(result.data(), a.data(), std::abs(b));
Chris@16 1591 }
Chris@16 1592
Chris@16 1593 inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x)
Chris@16 1594 {
Chris@16 1595 mpz_sqrtrem(s.data(), r.data(), x.data());
Chris@16 1596 }
Chris@16 1597
Chris@16 1598 inline unsigned eval_lsb(const gmp_int& val)
Chris@16 1599 {
Chris@16 1600 int c = eval_get_sign(val);
Chris@16 1601 if(c == 0)
Chris@16 1602 {
Chris@16 1603 BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
Chris@16 1604 }
Chris@16 1605 if(c < 0)
Chris@16 1606 {
Chris@16 1607 BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
Chris@16 1608 }
Chris@16 1609 return mpz_scan1(val.data(), 0);
Chris@16 1610 }
Chris@16 1611
Chris@16 1612 inline unsigned eval_msb(const gmp_int& val)
Chris@16 1613 {
Chris@16 1614 int c = eval_get_sign(val);
Chris@16 1615 if(c == 0)
Chris@16 1616 {
Chris@16 1617 BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
Chris@16 1618 }
Chris@16 1619 if(c < 0)
Chris@16 1620 {
Chris@16 1621 BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
Chris@16 1622 }
Chris@16 1623 return mpz_sizeinbase(val.data(), 2) - 1;
Chris@16 1624 }
Chris@16 1625
Chris@16 1626 inline bool eval_bit_test(const gmp_int& val, unsigned index)
Chris@16 1627 {
Chris@16 1628 return mpz_tstbit(val.data(), index) ? true : false;
Chris@16 1629 }
Chris@16 1630
Chris@16 1631 inline void eval_bit_set(gmp_int& val, unsigned index)
Chris@16 1632 {
Chris@16 1633 mpz_setbit(val.data(), index);
Chris@16 1634 }
Chris@16 1635
Chris@16 1636 inline void eval_bit_unset(gmp_int& val, unsigned index)
Chris@16 1637 {
Chris@16 1638 mpz_clrbit(val.data(), index);
Chris@16 1639 }
Chris@16 1640
Chris@16 1641 inline void eval_bit_flip(gmp_int& val, unsigned index)
Chris@16 1642 {
Chris@16 1643 mpz_combit(val.data(), index);
Chris@16 1644 }
Chris@16 1645
Chris@16 1646 inline void eval_qr(const gmp_int& x, const gmp_int& y,
Chris@16 1647 gmp_int& q, gmp_int& r)
Chris@16 1648 {
Chris@16 1649 mpz_tdiv_qr(q.data(), r.data(), x.data(), y.data());
Chris@16 1650 }
Chris@16 1651
Chris@16 1652 template <class Integer>
Chris@16 1653 inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
Chris@16 1654 {
Chris@16 1655 if((sizeof(Integer) <= sizeof(long)) || (val <= (std::numeric_limits<unsigned long>::max)()))
Chris@16 1656 {
Chris@16 1657 return mpz_tdiv_ui(x.data(), val);
Chris@16 1658 }
Chris@16 1659 else
Chris@16 1660 {
Chris@16 1661 return default_ops::eval_integer_modulus(x, val);
Chris@16 1662 }
Chris@16 1663 }
Chris@16 1664 template <class Integer>
Chris@16 1665 inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
Chris@16 1666 {
Chris@16 1667 typedef typename make_unsigned<Integer>::type unsigned_type;
Chris@16 1668 return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val)));
Chris@16 1669 }
Chris@16 1670 inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m)
Chris@16 1671 {
Chris@16 1672 if(eval_get_sign(p) < 0)
Chris@16 1673 {
Chris@16 1674 BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
Chris@16 1675 }
Chris@16 1676 mpz_powm(result.data(), base.data(), p.data(), m.data());
Chris@16 1677 }
Chris@16 1678
Chris@16 1679 template <class Integer>
Chris@16 1680 inline typename enable_if<
Chris@16 1681 mpl::and_<
Chris@16 1682 is_unsigned<Integer>,
Chris@16 1683 mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)>
Chris@16 1684 >
Chris@16 1685 >::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
Chris@16 1686 {
Chris@16 1687 mpz_powm_ui(result.data(), base.data(), p, m.data());
Chris@16 1688 }
Chris@16 1689 template <class Integer>
Chris@16 1690 inline typename enable_if<
Chris@16 1691 mpl::and_<
Chris@16 1692 is_signed<Integer>,
Chris@16 1693 mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)>
Chris@16 1694 >
Chris@16 1695 >::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
Chris@16 1696 {
Chris@16 1697 if(p < 0)
Chris@16 1698 {
Chris@16 1699 BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
Chris@16 1700 }
Chris@16 1701 mpz_powm_ui(result.data(), base.data(), p, m.data());
Chris@16 1702 }
Chris@16 1703
Chris@16 1704 struct gmp_rational;
Chris@16 1705 void eval_add(gmp_rational& t, const gmp_rational& o);
Chris@16 1706
Chris@16 1707 struct gmp_rational
Chris@16 1708 {
Chris@16 1709 typedef mpl::list<long, long long> signed_types;
Chris@16 1710 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
Chris@16 1711 typedef mpl::list<double, long double> float_types;
Chris@16 1712
Chris@16 1713 gmp_rational()
Chris@16 1714 {
Chris@16 1715 mpq_init(this->m_data);
Chris@16 1716 }
Chris@16 1717 gmp_rational(const gmp_rational& o)
Chris@16 1718 {
Chris@16 1719 mpq_init(m_data);
Chris@16 1720 if(o.m_data[0]._mp_num._mp_d)
Chris@16 1721 mpq_set(m_data, o.m_data);
Chris@16 1722 }
Chris@16 1723 gmp_rational(const gmp_int& o)
Chris@16 1724 {
Chris@16 1725 mpq_init(m_data);
Chris@16 1726 mpq_set_z(m_data, o.data());
Chris@16 1727 }
Chris@16 1728 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 1729 gmp_rational(gmp_rational&& o) BOOST_NOEXCEPT
Chris@16 1730 {
Chris@101 1731 m_data[0] = o.m_data[0];
Chris@16 1732 o.m_data[0]._mp_num._mp_d = 0;
Chris@16 1733 o.m_data[0]._mp_den._mp_d = 0;
Chris@16 1734 }
Chris@16 1735 #endif
Chris@16 1736 gmp_rational(const mpq_t o)
Chris@16 1737 {
Chris@16 1738 mpq_init(m_data);
Chris@16 1739 mpq_set(m_data, o);
Chris@16 1740 }
Chris@16 1741 gmp_rational(const mpz_t o)
Chris@16 1742 {
Chris@16 1743 mpq_init(m_data);
Chris@16 1744 mpq_set_z(m_data, o);
Chris@16 1745 }
Chris@16 1746 gmp_rational& operator = (const gmp_rational& o)
Chris@16 1747 {
Chris@16 1748 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1749 mpq_init(m_data);
Chris@16 1750 mpq_set(m_data, o.m_data);
Chris@16 1751 return *this;
Chris@16 1752 }
Chris@16 1753 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 1754 gmp_rational& operator = (gmp_rational&& o) BOOST_NOEXCEPT
Chris@16 1755 {
Chris@16 1756 mpq_swap(m_data, o.m_data);
Chris@16 1757 return *this;
Chris@16 1758 }
Chris@16 1759 #endif
Chris@16 1760 gmp_rational& operator = (unsigned long long i)
Chris@16 1761 {
Chris@16 1762 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1763 mpq_init(m_data);
Chris@16 1764 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
Chris@16 1765 unsigned shift = 0;
Chris@16 1766 mpq_t t;
Chris@16 1767 mpq_set_ui(m_data, 0, 1);
Chris@16 1768 mpq_init(t);
Chris@16 1769 while(i)
Chris@16 1770 {
Chris@16 1771 mpq_set_ui(t, static_cast<unsigned>(i & mask), 1);
Chris@16 1772 if(shift)
Chris@16 1773 mpq_mul_2exp(t, t, shift);
Chris@16 1774 mpq_add(m_data, m_data, t);
Chris@16 1775 shift += std::numeric_limits<unsigned>::digits;
Chris@16 1776 i >>= std::numeric_limits<unsigned>::digits;
Chris@16 1777 }
Chris@16 1778 mpq_clear(t);
Chris@16 1779 return *this;
Chris@16 1780 }
Chris@16 1781 gmp_rational& operator = (long long i)
Chris@16 1782 {
Chris@16 1783 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1784 mpq_init(m_data);
Chris@16 1785 bool neg = i < 0;
Chris@101 1786 *this = boost::multiprecision::detail::unsigned_abs(i);
Chris@16 1787 if(neg)
Chris@16 1788 mpq_neg(m_data, m_data);
Chris@16 1789 return *this;
Chris@16 1790 }
Chris@16 1791 gmp_rational& operator = (unsigned long i)
Chris@16 1792 {
Chris@16 1793 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1794 mpq_init(m_data);
Chris@16 1795 mpq_set_ui(m_data, i, 1);
Chris@16 1796 return *this;
Chris@16 1797 }
Chris@16 1798 gmp_rational& operator = (long i)
Chris@16 1799 {
Chris@16 1800 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1801 mpq_init(m_data);
Chris@16 1802 mpq_set_si(m_data, i, 1);
Chris@16 1803 return *this;
Chris@16 1804 }
Chris@16 1805 gmp_rational& operator = (double d)
Chris@16 1806 {
Chris@16 1807 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1808 mpq_init(m_data);
Chris@16 1809 mpq_set_d(m_data, d);
Chris@16 1810 return *this;
Chris@16 1811 }
Chris@16 1812 gmp_rational& operator = (long double a)
Chris@16 1813 {
Chris@16 1814 using std::frexp;
Chris@16 1815 using std::ldexp;
Chris@16 1816 using std::floor;
Chris@16 1817 using default_ops::eval_add;
Chris@16 1818 using default_ops::eval_subtract;
Chris@16 1819
Chris@16 1820 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1821 mpq_init(m_data);
Chris@16 1822
Chris@16 1823 if (a == 0) {
Chris@16 1824 mpq_set_si(m_data, 0, 1);
Chris@16 1825 return *this;
Chris@16 1826 }
Chris@16 1827
Chris@16 1828 if (a == 1) {
Chris@16 1829 mpq_set_si(m_data, 1, 1);
Chris@16 1830 return *this;
Chris@16 1831 }
Chris@16 1832
Chris@16 1833 BOOST_ASSERT(!(boost::math::isinf)(a));
Chris@16 1834 BOOST_ASSERT(!(boost::math::isnan)(a));
Chris@16 1835
Chris@16 1836 int e;
Chris@16 1837 long double f, term;
Chris@16 1838 mpq_set_ui(m_data, 0, 1);
Chris@16 1839 mpq_set_ui(m_data, 0u, 1);
Chris@16 1840 gmp_rational t;
Chris@16 1841
Chris@16 1842 f = frexp(a, &e);
Chris@16 1843
Chris@16 1844 static const int shift = std::numeric_limits<int>::digits - 1;
Chris@16 1845
Chris@16 1846 while(f)
Chris@16 1847 {
Chris@16 1848 // extract int sized bits from f:
Chris@16 1849 f = ldexp(f, shift);
Chris@16 1850 term = floor(f);
Chris@16 1851 e -= shift;
Chris@16 1852 mpq_mul_2exp(m_data, m_data, shift);
Chris@16 1853 t = static_cast<long>(term);
Chris@16 1854 eval_add(*this, t);
Chris@16 1855 f -= term;
Chris@16 1856 }
Chris@16 1857 if(e > 0)
Chris@16 1858 mpq_mul_2exp(m_data, m_data, e);
Chris@16 1859 else if(e < 0)
Chris@16 1860 mpq_div_2exp(m_data, m_data, -e);
Chris@16 1861 return *this;
Chris@16 1862 }
Chris@16 1863 gmp_rational& operator = (const char* s)
Chris@16 1864 {
Chris@16 1865 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1866 mpq_init(m_data);
Chris@16 1867 if(0 != mpq_set_str(m_data, s, 10))
Chris@16 1868 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid rational number.")));
Chris@16 1869 return *this;
Chris@16 1870 }
Chris@16 1871 gmp_rational& operator=(const gmp_int& o)
Chris@16 1872 {
Chris@16 1873 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1874 mpq_init(m_data);
Chris@16 1875 mpq_set_z(m_data, o.data());
Chris@16 1876 return *this;
Chris@16 1877 }
Chris@16 1878 gmp_rational& operator=(const mpq_t o)
Chris@16 1879 {
Chris@16 1880 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1881 mpq_init(m_data);
Chris@16 1882 mpq_set(m_data, o);
Chris@16 1883 return *this;
Chris@16 1884 }
Chris@16 1885 gmp_rational& operator=(const mpz_t o)
Chris@16 1886 {
Chris@16 1887 if(m_data[0]._mp_den._mp_d == 0)
Chris@16 1888 mpq_init(m_data);
Chris@16 1889 mpq_set_z(m_data, o);
Chris@16 1890 return *this;
Chris@16 1891 }
Chris@16 1892 void swap(gmp_rational& o)
Chris@16 1893 {
Chris@16 1894 mpq_swap(m_data, o.m_data);
Chris@16 1895 }
Chris@16 1896 std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags /*f*/)const
Chris@16 1897 {
Chris@16 1898 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
Chris@16 1899 // TODO make a better job of this including handling of f!!
Chris@16 1900 void *(*alloc_func_ptr) (size_t);
Chris@16 1901 void *(*realloc_func_ptr) (void *, size_t, size_t);
Chris@16 1902 void (*free_func_ptr) (void *, size_t);
Chris@16 1903 const char* ps = mpq_get_str (0, 10, m_data);
Chris@16 1904 std::string s = ps;
Chris@16 1905 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
Chris@16 1906 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
Chris@16 1907 return s;
Chris@16 1908 }
Chris@16 1909 ~gmp_rational()
Chris@16 1910 {
Chris@16 1911 if(m_data[0]._mp_num._mp_d || m_data[0]._mp_den._mp_d)
Chris@16 1912 mpq_clear(m_data);
Chris@16 1913 }
Chris@16 1914 void negate()
Chris@16 1915 {
Chris@16 1916 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
Chris@16 1917 mpq_neg(m_data, m_data);
Chris@16 1918 }
Chris@16 1919 int compare(const gmp_rational& o)const
Chris@16 1920 {
Chris@16 1921 BOOST_ASSERT(m_data[0]._mp_num._mp_d && o.m_data[0]._mp_num._mp_d);
Chris@16 1922 return mpq_cmp(m_data, o.m_data);
Chris@16 1923 }
Chris@16 1924 template <class V>
Chris@16 1925 int compare(V v)const
Chris@16 1926 {
Chris@16 1927 gmp_rational d;
Chris@16 1928 d = v;
Chris@16 1929 return compare(d);
Chris@16 1930 }
Chris@16 1931 int compare(unsigned long v)const
Chris@16 1932 {
Chris@16 1933 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
Chris@16 1934 return mpq_cmp_ui(m_data, v, 1);
Chris@16 1935 }
Chris@16 1936 int compare(long v)const
Chris@16 1937 {
Chris@16 1938 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
Chris@16 1939 return mpq_cmp_si(m_data, v, 1);
Chris@16 1940 }
Chris@16 1941 mpq_t& data()
Chris@16 1942 {
Chris@16 1943 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
Chris@16 1944 return m_data;
Chris@16 1945 }
Chris@16 1946 const mpq_t& data()const
Chris@16 1947 {
Chris@16 1948 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
Chris@16 1949 return m_data;
Chris@16 1950 }
Chris@16 1951 protected:
Chris@16 1952 mpq_t m_data;
Chris@16 1953 };
Chris@16 1954
Chris@16 1955 inline bool eval_is_zero(const gmp_rational& val)
Chris@16 1956 {
Chris@16 1957 return mpq_sgn(val.data()) == 0;
Chris@16 1958 }
Chris@16 1959 template <class T>
Chris@16 1960 inline bool eval_eq(gmp_rational& a, const T& b)
Chris@16 1961 {
Chris@16 1962 return a.compare(b) == 0;
Chris@16 1963 }
Chris@16 1964 template <class T>
Chris@16 1965 inline bool eval_lt(gmp_rational& a, const T& b)
Chris@16 1966 {
Chris@16 1967 return a.compare(b) < 0;
Chris@16 1968 }
Chris@16 1969 template <class T>
Chris@16 1970 inline bool eval_gt(gmp_rational& a, const T& b)
Chris@16 1971 {
Chris@16 1972 return a.compare(b) > 0;
Chris@16 1973 }
Chris@16 1974
Chris@16 1975 inline void eval_add(gmp_rational& t, const gmp_rational& o)
Chris@16 1976 {
Chris@16 1977 mpq_add(t.data(), t.data(), o.data());
Chris@16 1978 }
Chris@16 1979 inline void eval_subtract(gmp_rational& t, const gmp_rational& o)
Chris@16 1980 {
Chris@16 1981 mpq_sub(t.data(), t.data(), o.data());
Chris@16 1982 }
Chris@16 1983 inline void eval_multiply(gmp_rational& t, const gmp_rational& o)
Chris@16 1984 {
Chris@16 1985 mpq_mul(t.data(), t.data(), o.data());
Chris@16 1986 }
Chris@16 1987 inline void eval_divide(gmp_rational& t, const gmp_rational& o)
Chris@16 1988 {
Chris@16 1989 if(eval_is_zero(o))
Chris@16 1990 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 1991 mpq_div(t.data(), t.data(), o.data());
Chris@16 1992 }
Chris@16 1993 inline void eval_add(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
Chris@16 1994 {
Chris@16 1995 mpq_add(t.data(), p.data(), o.data());
Chris@16 1996 }
Chris@16 1997 inline void eval_subtract(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
Chris@16 1998 {
Chris@16 1999 mpq_sub(t.data(), p.data(), o.data());
Chris@16 2000 }
Chris@16 2001 inline void eval_multiply(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
Chris@16 2002 {
Chris@16 2003 mpq_mul(t.data(), p.data(), o.data());
Chris@16 2004 }
Chris@16 2005 inline void eval_divide(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
Chris@16 2006 {
Chris@16 2007 if(eval_is_zero(o))
Chris@16 2008 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
Chris@16 2009 mpq_div(t.data(), p.data(), o.data());
Chris@16 2010 }
Chris@16 2011
Chris@16 2012 inline int eval_get_sign(const gmp_rational& val)
Chris@16 2013 {
Chris@16 2014 return mpq_sgn(val.data());
Chris@16 2015 }
Chris@16 2016 inline void eval_convert_to(double* result, const gmp_rational& val)
Chris@16 2017 {
Chris@101 2018 //
Chris@101 2019 // This does not round correctly:
Chris@101 2020 //
Chris@101 2021 //*result = mpq_get_d(val.data());
Chris@101 2022 //
Chris@101 2023 // This does:
Chris@101 2024 //
Chris@101 2025 boost::multiprecision::detail::generic_convert_rational_to_float(*result, val);
Chris@16 2026 }
Chris@16 2027
Chris@16 2028 inline void eval_convert_to(long* result, const gmp_rational& val)
Chris@16 2029 {
Chris@16 2030 double r;
Chris@16 2031 eval_convert_to(&r, val);
Chris@16 2032 *result = static_cast<long>(r);
Chris@16 2033 }
Chris@16 2034
Chris@16 2035 inline void eval_convert_to(unsigned long* result, const gmp_rational& val)
Chris@16 2036 {
Chris@16 2037 double r;
Chris@16 2038 eval_convert_to(&r, val);
Chris@16 2039 *result = static_cast<long>(r);
Chris@16 2040 }
Chris@16 2041
Chris@16 2042 inline void eval_abs(gmp_rational& result, const gmp_rational& val)
Chris@16 2043 {
Chris@16 2044 mpq_abs(result.data(), val.data());
Chris@16 2045 }
Chris@16 2046
Chris@16 2047 inline void assign_components(gmp_rational& result, unsigned long v1, unsigned long v2)
Chris@16 2048 {
Chris@16 2049 mpq_set_ui(result.data(), v1, v2);
Chris@16 2050 mpq_canonicalize(result.data());
Chris@16 2051 }
Chris@16 2052 inline void assign_components(gmp_rational& result, long v1, long v2)
Chris@16 2053 {
Chris@16 2054 mpq_set_si(result.data(), v1, v2);
Chris@16 2055 mpq_canonicalize(result.data());
Chris@16 2056 }
Chris@16 2057 inline void assign_components(gmp_rational& result, gmp_int const& v1, gmp_int const& v2)
Chris@16 2058 {
Chris@16 2059 mpz_set(mpq_numref(result.data()), v1.data());
Chris@16 2060 mpz_set(mpq_denref(result.data()), v2.data());
Chris@16 2061 mpq_canonicalize(result.data());
Chris@16 2062 }
Chris@16 2063
Chris@16 2064 //
Chris@16 2065 // Some member functions that are dependent upon previous code go here:
Chris@16 2066 //
Chris@16 2067 template <unsigned Digits10>
Chris@16 2068 template <unsigned D>
Chris@16 2069 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= Digits10>::type*)
Chris@16 2070 {
Chris@16 2071 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
Chris@16 2072 mpf_set(this->m_data, o.data());
Chris@16 2073 }
Chris@16 2074 template <unsigned Digits10>
Chris@16 2075 template <unsigned D>
Chris@16 2076 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= Digits10>::type*)
Chris@16 2077 {
Chris@16 2078 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
Chris@16 2079 mpf_set(this->m_data, o.data());
Chris@16 2080 }
Chris@16 2081 template <unsigned Digits10>
Chris@16 2082 inline gmp_float<Digits10>::gmp_float(const gmp_int& o)
Chris@16 2083 {
Chris@16 2084 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
Chris@16 2085 mpf_set_z(this->data(), o.data());
Chris@16 2086 }
Chris@16 2087 template <unsigned Digits10>
Chris@16 2088 inline gmp_float<Digits10>::gmp_float(const gmp_rational& o)
Chris@16 2089 {
Chris@16 2090 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
Chris@16 2091 mpf_set_q(this->data(), o.data());
Chris@16 2092 }
Chris@16 2093 template <unsigned Digits10>
Chris@16 2094 template <unsigned D>
Chris@16 2095 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_float<D>& o)
Chris@16 2096 {
Chris@16 2097 if(this->m_data[0]._mp_d == 0)
Chris@16 2098 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
Chris@16 2099 mpf_set(this->m_data, o.data());
Chris@16 2100 return *this;
Chris@16 2101 }
Chris@16 2102 template <unsigned Digits10>
Chris@16 2103 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_int& o)
Chris@16 2104 {
Chris@16 2105 if(this->m_data[0]._mp_d == 0)
Chris@16 2106 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
Chris@16 2107 mpf_set_z(this->data(), o.data());
Chris@16 2108 return *this;
Chris@16 2109 }
Chris@16 2110 template <unsigned Digits10>
Chris@16 2111 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_rational& o)
Chris@16 2112 {
Chris@16 2113 if(this->m_data[0]._mp_d == 0)
Chris@16 2114 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
Chris@16 2115 mpf_set_q(this->data(), o.data());
Chris@16 2116 return *this;
Chris@16 2117 }
Chris@16 2118 inline gmp_float<0>::gmp_float(const gmp_int& o)
Chris@16 2119 {
Chris@16 2120 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 2121 mpf_set_z(this->data(), o.data());
Chris@16 2122 }
Chris@16 2123 inline gmp_float<0>::gmp_float(const gmp_rational& o)
Chris@16 2124 {
Chris@16 2125 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
Chris@16 2126 mpf_set_q(this->data(), o.data());
Chris@16 2127 }
Chris@16 2128 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_int& o)
Chris@16 2129 {
Chris@16 2130 if(this->m_data[0]._mp_d == 0)
Chris@16 2131 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision()));
Chris@16 2132 mpf_set_z(this->data(), o.data());
Chris@16 2133 return *this;
Chris@16 2134 }
Chris@16 2135 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_rational& o)
Chris@16 2136 {
Chris@16 2137 if(this->m_data[0]._mp_d == 0)
Chris@16 2138 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision()));
Chris@16 2139 mpf_set_q(this->data(), o.data());
Chris@16 2140 return *this;
Chris@16 2141 }
Chris@16 2142 inline gmp_int::gmp_int(const gmp_rational& o)
Chris@16 2143 {
Chris@16 2144 mpz_init(this->m_data);
Chris@16 2145 mpz_set_q(this->m_data, o.data());
Chris@16 2146 }
Chris@16 2147 inline gmp_int& gmp_int::operator=(const gmp_rational& o)
Chris@16 2148 {
Chris@16 2149 if(this->m_data[0]._mp_d == 0)
Chris@16 2150 mpz_init(this->m_data);
Chris@16 2151 mpz_set_q(this->m_data, o.data());
Chris@16 2152 return *this;
Chris@16 2153 }
Chris@16 2154
Chris@16 2155 } //namespace backends
Chris@16 2156
Chris@16 2157 using boost::multiprecision::backends::gmp_int;
Chris@16 2158 using boost::multiprecision::backends::gmp_rational;
Chris@16 2159 using boost::multiprecision::backends::gmp_float;
Chris@16 2160
Chris@16 2161 template <>
Chris@16 2162 struct component_type<number<gmp_rational> >
Chris@16 2163 {
Chris@16 2164 typedef number<gmp_int> type;
Chris@16 2165 };
Chris@16 2166
Chris@16 2167 template <expression_template_option ET>
Chris@16 2168 inline number<gmp_int, ET> numerator(const number<gmp_rational, ET>& val)
Chris@16 2169 {
Chris@16 2170 number<gmp_int, ET> result;
Chris@16 2171 mpz_set(result.backend().data(), (mpq_numref(val.backend().data())));
Chris@16 2172 return result;
Chris@16 2173 }
Chris@16 2174 template <expression_template_option ET>
Chris@16 2175 inline number<gmp_int, ET> denominator(const number<gmp_rational, ET>& val)
Chris@16 2176 {
Chris@16 2177 number<gmp_int, ET> result;
Chris@16 2178 mpz_set(result.backend().data(), (mpq_denref(val.backend().data())));
Chris@16 2179 return result;
Chris@16 2180 }
Chris@16 2181
Chris@16 2182 #ifdef BOOST_NO_SFINAE_EXPR
Chris@16 2183
Chris@16 2184 namespace detail{
Chris@16 2185
Chris@16 2186 template<>
Chris@16 2187 struct is_explicitly_convertible<canonical<mpf_t, gmp_int>::type, gmp_int> : public mpl::true_ {};
Chris@16 2188 template<>
Chris@16 2189 struct is_explicitly_convertible<canonical<mpq_t, gmp_int>::type, gmp_int> : public mpl::true_ {};
Chris@16 2190 template<unsigned Digits10>
Chris@16 2191 struct is_explicitly_convertible<gmp_float<Digits10>, gmp_int> : public mpl::true_ {};
Chris@16 2192 template<>
Chris@16 2193 struct is_explicitly_convertible<gmp_rational, gmp_int> : public mpl::true_ {};
Chris@16 2194 template<unsigned D1, unsigned D2>
Chris@16 2195 struct is_explicitly_convertible<gmp_float<D1>, gmp_float<D2> > : public mpl::true_ {};
Chris@16 2196
Chris@16 2197 }
Chris@16 2198
Chris@16 2199 #endif
Chris@16 2200
Chris@16 2201 template<>
Chris@16 2202 struct number_category<detail::canonical<mpz_t, gmp_int>::type> : public mpl::int_<number_kind_integer>{};
Chris@16 2203 template<>
Chris@16 2204 struct number_category<detail::canonical<mpq_t, gmp_rational>::type> : public mpl::int_<number_kind_rational>{};
Chris@16 2205 template<>
Chris@16 2206 struct number_category<detail::canonical<mpf_t, gmp_float<0> >::type> : public mpl::int_<number_kind_floating_point>{};
Chris@16 2207
Chris@16 2208
Chris@16 2209 typedef number<gmp_float<50> > mpf_float_50;
Chris@16 2210 typedef number<gmp_float<100> > mpf_float_100;
Chris@16 2211 typedef number<gmp_float<500> > mpf_float_500;
Chris@16 2212 typedef number<gmp_float<1000> > mpf_float_1000;
Chris@16 2213 typedef number<gmp_float<0> > mpf_float;
Chris@16 2214 typedef number<gmp_int > mpz_int;
Chris@16 2215 typedef number<gmp_rational > mpq_rational;
Chris@16 2216
Chris@16 2217 }} // namespaces
Chris@16 2218
Chris@16 2219 namespace std{
Chris@16 2220
Chris@16 2221 //
Chris@16 2222 // numeric_limits [partial] specializations for the types declared in this header:
Chris@16 2223 //
Chris@16 2224 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2225 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >
Chris@16 2226 {
Chris@16 2227 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> number_type;
Chris@16 2228 public:
Chris@16 2229 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
Chris@16 2230 //
Chris@16 2231 // min and max values chosen so as to not cause segfaults when calling
Chris@16 2232 // mpf_get_str on 64-bit Linux builds. Possibly we could use larger
Chris@16 2233 // exponent values elsewhere.
Chris@16 2234 //
Chris@16 2235 static number_type (min)()
Chris@16 2236 {
Chris@16 2237 initializer.do_nothing();
Chris@16 2238 static std::pair<bool, number_type> value;
Chris@16 2239 if(!value.first)
Chris@16 2240 {
Chris@16 2241 value.first = true;
Chris@16 2242 value.second = 1;
Chris@16 2243 mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
Chris@16 2244 }
Chris@16 2245 return value.second;
Chris@16 2246 }
Chris@16 2247 static number_type (max)()
Chris@16 2248 {
Chris@16 2249 initializer.do_nothing();
Chris@16 2250 static std::pair<bool, number_type> value;
Chris@16 2251 if(!value.first)
Chris@16 2252 {
Chris@16 2253 value.first = true;
Chris@16 2254 value.second = 1;
Chris@16 2255 mpf_mul_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
Chris@16 2256 }
Chris@16 2257 return value.second;
Chris@16 2258 }
Chris@16 2259 BOOST_STATIC_CONSTEXPR number_type lowest()
Chris@16 2260 {
Chris@16 2261 return -(max)();
Chris@16 2262 }
Chris@16 2263 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301L ? 2 : 1));
Chris@16 2264 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
Chris@16 2265 // Have to allow for a possible extra limb inside the gmp data structure:
Chris@16 2266 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2 + ((GMP_LIMB_BITS * 301L) / 1000L);
Chris@16 2267 BOOST_STATIC_CONSTEXPR bool is_signed = true;
Chris@16 2268 BOOST_STATIC_CONSTEXPR bool is_integer = false;
Chris@16 2269 BOOST_STATIC_CONSTEXPR bool is_exact = false;
Chris@16 2270 BOOST_STATIC_CONSTEXPR int radix = 2;
Chris@16 2271 static number_type epsilon()
Chris@16 2272 {
Chris@16 2273 initializer.do_nothing();
Chris@16 2274 static std::pair<bool, number_type> value;
Chris@16 2275 if(!value.first)
Chris@16 2276 {
Chris@16 2277 value.first = true;
Chris@16 2278 value.second = 1;
Chris@16 2279 mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
Chris@16 2280 }
Chris@16 2281 return value.second;
Chris@16 2282 }
Chris@16 2283 // What value should this be????
Chris@16 2284 static number_type round_error()
Chris@16 2285 {
Chris@16 2286 // returns epsilon/2
Chris@16 2287 initializer.do_nothing();
Chris@16 2288 static std::pair<bool, number_type> value;
Chris@16 2289 if(!value.first)
Chris@16 2290 {
Chris@16 2291 value.first = true;
Chris@16 2292 value.second = 1;
Chris@16 2293 }
Chris@16 2294 return value.second;
Chris@16 2295 }
Chris@16 2296 BOOST_STATIC_CONSTEXPR long min_exponent = LONG_MIN;
Chris@16 2297 BOOST_STATIC_CONSTEXPR long min_exponent10 = (LONG_MIN / 1000) * 301L;
Chris@16 2298 BOOST_STATIC_CONSTEXPR long max_exponent = LONG_MAX;
Chris@16 2299 BOOST_STATIC_CONSTEXPR long max_exponent10 = (LONG_MAX / 1000) * 301L;
Chris@16 2300 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
Chris@16 2301 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
Chris@16 2302 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
Chris@16 2303 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
Chris@16 2304 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
Chris@16 2305 BOOST_STATIC_CONSTEXPR number_type infinity() { return number_type(); }
Chris@16 2306 BOOST_STATIC_CONSTEXPR number_type quiet_NaN() { return number_type(); }
Chris@16 2307 BOOST_STATIC_CONSTEXPR number_type signaling_NaN() { return number_type(); }
Chris@16 2308 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(); }
Chris@16 2309 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
Chris@16 2310 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
Chris@16 2311 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
Chris@16 2312 BOOST_STATIC_CONSTEXPR bool traps = true;
Chris@16 2313 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
Chris@16 2314 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate;
Chris@16 2315
Chris@16 2316 private:
Chris@16 2317 struct data_initializer
Chris@16 2318 {
Chris@16 2319 data_initializer()
Chris@16 2320 {
Chris@16 2321 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::epsilon();
Chris@16 2322 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::round_error();
Chris@16 2323 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::min)();
Chris@16 2324 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::max)();
Chris@16 2325 }
Chris@16 2326 void do_nothing()const{}
Chris@16 2327 };
Chris@16 2328 static const data_initializer initializer;
Chris@16 2329 };
Chris@16 2330
Chris@16 2331 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2332 const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::initializer;
Chris@16 2333
Chris@101 2334 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
Chris@101 2335
Chris@101 2336 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2337 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits;
Chris@101 2338 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2339 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits10;
Chris@101 2340 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2341 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_digits10;
Chris@101 2342 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2343 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_signed;
Chris@101 2344 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2345 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_integer;
Chris@101 2346 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2347 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_exact;
Chris@101 2348 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2349 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::radix;
Chris@101 2350 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2351 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent;
Chris@101 2352 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2353 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent10;
Chris@101 2354 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2355 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent;
Chris@101 2356 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2357 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent10;
Chris@101 2358 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2359 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_infinity;
Chris@101 2360 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2361 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
Chris@101 2362 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2363 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
Chris@101 2364 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2365 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm;
Chris@101 2366 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2367 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm_loss;
Chris@101 2368 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2369 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_iec559;
Chris@101 2370 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2371 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_bounded;
Chris@101 2372 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2373 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_modulo;
Chris@101 2374 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2375 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::traps;
Chris@101 2376 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2377 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::tinyness_before;
Chris@101 2378 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@101 2379 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::round_style;
Chris@101 2380
Chris@101 2381 #endif
Chris@101 2382
Chris@16 2383 template<boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2384 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >
Chris@16 2385 {
Chris@16 2386 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> number_type;
Chris@16 2387 public:
Chris@16 2388 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
Chris@16 2389 static number_type (min)() { return number_type(); }
Chris@16 2390 static number_type (max)() { return number_type(); }
Chris@16 2391 static number_type lowest() { return number_type(); }
Chris@16 2392 BOOST_STATIC_CONSTEXPR int digits = 0;
Chris@16 2393 BOOST_STATIC_CONSTEXPR int digits10 = 0;
Chris@16 2394 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
Chris@16 2395 BOOST_STATIC_CONSTEXPR bool is_signed = false;
Chris@16 2396 BOOST_STATIC_CONSTEXPR bool is_integer = false;
Chris@16 2397 BOOST_STATIC_CONSTEXPR bool is_exact = false;
Chris@16 2398 BOOST_STATIC_CONSTEXPR int radix = 0;
Chris@16 2399 static number_type epsilon() { return number_type(); }
Chris@16 2400 static number_type round_error() { return number_type(); }
Chris@16 2401 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
Chris@16 2402 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
Chris@16 2403 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
Chris@16 2404 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
Chris@16 2405 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
Chris@16 2406 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
Chris@16 2407 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
Chris@16 2408 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
Chris@16 2409 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
Chris@16 2410 static number_type infinity() { return number_type(); }
Chris@16 2411 static number_type quiet_NaN() { return number_type(); }
Chris@16 2412 static number_type signaling_NaN() { return number_type(); }
Chris@16 2413 static number_type denorm_min() { return number_type(); }
Chris@16 2414 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
Chris@16 2415 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
Chris@16 2416 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
Chris@16 2417 BOOST_STATIC_CONSTEXPR bool traps = false;
Chris@16 2418 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
Chris@16 2419 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate;
Chris@16 2420 };
Chris@16 2421
Chris@16 2422 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
Chris@16 2423
Chris@16 2424 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2425 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits;
Chris@16 2426 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2427 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits10;
Chris@16 2428 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2429 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_digits10;
Chris@16 2430 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2431 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_signed;
Chris@16 2432 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2433 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_integer;
Chris@16 2434 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2435 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_exact;
Chris@16 2436 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2437 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::radix;
Chris@16 2438 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2439 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent;
Chris@16 2440 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2441 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent10;
Chris@16 2442 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2443 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent;
Chris@16 2444 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2445 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent10;
Chris@16 2446 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2447 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_infinity;
Chris@16 2448 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2449 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_quiet_NaN;
Chris@16 2450 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2451 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_signaling_NaN;
Chris@16 2452 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2453 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm;
Chris@16 2454 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2455 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm_loss;
Chris@16 2456 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2457 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_iec559;
Chris@16 2458 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2459 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_bounded;
Chris@16 2460 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2461 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_modulo;
Chris@16 2462 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2463 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::traps;
Chris@16 2464 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2465 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::tinyness_before;
Chris@16 2466 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2467 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::round_style;
Chris@16 2468
Chris@16 2469 #endif
Chris@16 2470
Chris@16 2471 template<boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2472 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >
Chris@16 2473 {
Chris@16 2474 typedef boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> number_type;
Chris@16 2475 public:
Chris@16 2476 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
Chris@16 2477 //
Chris@16 2478 // Largest and smallest numbers are bounded only by available memory, set
Chris@16 2479 // to zero:
Chris@16 2480 //
Chris@16 2481 static number_type (min)()
Chris@16 2482 {
Chris@16 2483 return number_type();
Chris@16 2484 }
Chris@16 2485 static number_type (max)()
Chris@16 2486 {
Chris@16 2487 return number_type();
Chris@16 2488 }
Chris@16 2489 static number_type lowest() { return (min)(); }
Chris@16 2490 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
Chris@16 2491 BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
Chris@16 2492 BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
Chris@16 2493 BOOST_STATIC_CONSTEXPR bool is_signed = true;
Chris@16 2494 BOOST_STATIC_CONSTEXPR bool is_integer = true;
Chris@16 2495 BOOST_STATIC_CONSTEXPR bool is_exact = true;
Chris@16 2496 BOOST_STATIC_CONSTEXPR int radix = 2;
Chris@16 2497 static number_type epsilon() { return number_type(); }
Chris@16 2498 static number_type round_error() { return number_type(); }
Chris@16 2499 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
Chris@16 2500 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
Chris@16 2501 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
Chris@16 2502 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
Chris@16 2503 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
Chris@16 2504 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
Chris@16 2505 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
Chris@16 2506 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
Chris@16 2507 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
Chris@16 2508 static number_type infinity() { return number_type(); }
Chris@16 2509 static number_type quiet_NaN() { return number_type(); }
Chris@16 2510 static number_type signaling_NaN() { return number_type(); }
Chris@16 2511 static number_type denorm_min() { return number_type(); }
Chris@16 2512 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
Chris@16 2513 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
Chris@16 2514 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
Chris@16 2515 BOOST_STATIC_CONSTEXPR bool traps = false;
Chris@16 2516 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
Chris@16 2517 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
Chris@16 2518 };
Chris@16 2519
Chris@16 2520 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
Chris@16 2521
Chris@16 2522 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2523 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits;
Chris@16 2524 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2525 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits10;
Chris@16 2526 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2527 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_digits10;
Chris@16 2528 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2529 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_signed;
Chris@16 2530 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2531 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_integer;
Chris@16 2532 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2533 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_exact;
Chris@16 2534 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2535 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::radix;
Chris@16 2536 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2537 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent;
Chris@16 2538 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2539 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent10;
Chris@16 2540 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2541 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent;
Chris@16 2542 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2543 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent10;
Chris@16 2544 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2545 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_infinity;
Chris@16 2546 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2547 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_quiet_NaN;
Chris@16 2548 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2549 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_signaling_NaN;
Chris@16 2550 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2551 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm;
Chris@16 2552 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2553 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm_loss;
Chris@16 2554 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2555 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_iec559;
Chris@16 2556 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2557 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_bounded;
Chris@16 2558 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2559 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_modulo;
Chris@16 2560 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2561 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::traps;
Chris@16 2562 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2563 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::tinyness_before;
Chris@16 2564 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2565 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::round_style;
Chris@16 2566
Chris@16 2567 #endif
Chris@16 2568
Chris@16 2569 template<boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2570 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >
Chris@16 2571 {
Chris@16 2572 typedef boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> number_type;
Chris@16 2573 public:
Chris@16 2574 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
Chris@16 2575 //
Chris@16 2576 // Largest and smallest numbers are bounded only by available memory, set
Chris@16 2577 // to zero:
Chris@16 2578 //
Chris@16 2579 static number_type (min)()
Chris@16 2580 {
Chris@16 2581 return number_type();
Chris@16 2582 }
Chris@16 2583 static number_type (max)()
Chris@16 2584 {
Chris@16 2585 return number_type();
Chris@16 2586 }
Chris@16 2587 static number_type lowest() { return (min)(); }
Chris@16 2588 // Digits are unbounded, use zero for now:
Chris@16 2589 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
Chris@16 2590 BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
Chris@16 2591 BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
Chris@16 2592 BOOST_STATIC_CONSTEXPR bool is_signed = true;
Chris@16 2593 BOOST_STATIC_CONSTEXPR bool is_integer = false;
Chris@16 2594 BOOST_STATIC_CONSTEXPR bool is_exact = true;
Chris@16 2595 BOOST_STATIC_CONSTEXPR int radix = 2;
Chris@16 2596 static number_type epsilon() { return number_type(); }
Chris@16 2597 static number_type round_error() { return number_type(); }
Chris@16 2598 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
Chris@16 2599 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
Chris@16 2600 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
Chris@16 2601 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
Chris@16 2602 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
Chris@16 2603 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
Chris@16 2604 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
Chris@16 2605 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
Chris@16 2606 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
Chris@16 2607 static number_type infinity() { return number_type(); }
Chris@16 2608 static number_type quiet_NaN() { return number_type(); }
Chris@16 2609 static number_type signaling_NaN() { return number_type(); }
Chris@16 2610 static number_type denorm_min() { return number_type(); }
Chris@16 2611 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
Chris@16 2612 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
Chris@16 2613 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
Chris@16 2614 BOOST_STATIC_CONSTEXPR bool traps = false;
Chris@16 2615 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
Chris@16 2616 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
Chris@16 2617 };
Chris@16 2618
Chris@16 2619 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
Chris@16 2620
Chris@16 2621 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2622 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits;
Chris@16 2623 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2624 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits10;
Chris@16 2625 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2626 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_digits10;
Chris@16 2627 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2628 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_signed;
Chris@16 2629 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2630 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_integer;
Chris@16 2631 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2632 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_exact;
Chris@16 2633 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2634 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::radix;
Chris@16 2635 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2636 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent;
Chris@16 2637 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2638 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent10;
Chris@16 2639 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2640 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent;
Chris@16 2641 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2642 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent10;
Chris@16 2643 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2644 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_infinity;
Chris@16 2645 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2646 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_quiet_NaN;
Chris@16 2647 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2648 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_signaling_NaN;
Chris@16 2649 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2650 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm;
Chris@16 2651 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2652 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm_loss;
Chris@16 2653 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2654 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_iec559;
Chris@16 2655 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2656 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_bounded;
Chris@16 2657 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2658 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_modulo;
Chris@16 2659 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2660 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::traps;
Chris@16 2661 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2662 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::tinyness_before;
Chris@16 2663 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 2664 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::round_style;
Chris@16 2665
Chris@16 2666 #endif
Chris@16 2667
Chris@16 2668 #ifdef BOOST_MSVC
Chris@16 2669 #pragma warning(pop)
Chris@16 2670 #endif
Chris@16 2671
Chris@16 2672 } // namespace std
Chris@16 2673
Chris@16 2674 #endif