1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright 2011 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_MATH_ER_GMP_BACKEND_HPP
7 #define BOOST_MATH_ER_GMP_BACKEND_HPP
9 #include <boost/multiprecision/number.hpp>
10 #include <boost/multiprecision/debug_adaptor.hpp>
11 #include <boost/multiprecision/detail/integer_ops.hpp>
12 #include <boost/multiprecision/detail/big_lanczos.hpp>
13 #include <boost/multiprecision/detail/digits.hpp>
14 #include <boost/math/special_functions/fpclassify.hpp>
15 #include <boost/cstdint.hpp>
16 #include <boost/functional/hash_fwd.hpp>
18 // Some includes we need from Boost.Math, since we rely on that library to provide these functions:
20 #include <boost/math/special_functions/asinh.hpp>
21 #include <boost/math/special_functions/acosh.hpp>
22 #include <boost/math/special_functions/atanh.hpp>
23 #include <boost/math/special_functions/cbrt.hpp>
24 #include <boost/math/special_functions/expm1.hpp>
25 #include <boost/math/special_functions/gamma.hpp>
28 # pragma warning(push)
29 # pragma warning(disable:4127)
36 #if defined(__MPIR_VERSION) && defined(__MPIR_VERSION_MINOR) && defined(__MPIR_VERSION_PATCHLEVEL)
37 # define BOOST_MP_MPIR_VERSION (__MPIR_VERSION * 10000 + __MPIR_VERSION_MINOR * 100 + __MPIR_VERSION_PATCHLEVEL)
39 # define BOOST_MP_MPIR_VERSION 0
47 namespace multiprecision{
51 // warning C4127: conditional expression is constant
53 #pragma warning(disable:4127)
56 template <unsigned digits10>
61 } // namespace backends
64 struct number_category<backends::gmp_int> : public mpl::int_<number_kind_integer>{};
66 struct number_category<backends::gmp_rational> : public mpl::int_<number_kind_rational>{};
67 template <unsigned digits10>
68 struct number_category<backends::gmp_float<digits10> > : public mpl::int_<number_kind_floating_point>{};
72 // Within this file, the only functions we mark as noexcept are those that manipulate
73 // (but don't create) an mpf_t. All other types may allocate at pretty much any time
74 // via a user-supplied allocator, and therefore throw.
78 template <unsigned digits10>
81 #ifdef BOOST_HAS_LONG_LONG
82 typedef mpl::list<long, boost::long_long_type> signed_types;
83 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
85 typedef mpl::list<long> signed_types;
86 typedef mpl::list<unsigned long> unsigned_types;
88 typedef mpl::list<double, long double> float_types;
89 typedef long exponent_type;
91 gmp_float_imp() BOOST_NOEXCEPT {}
93 gmp_float_imp(const gmp_float_imp& o)
96 // We have to do an init followed by a set here, otherwise *this may be at
97 // a lower precision than o: seems like mpf_init_set copies just enough bits
98 // to get the right value, but if it's then used in further calculations
99 // things go badly wrong!!
101 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
102 if(o.m_data[0]._mp_d)
103 mpf_set(m_data, o.m_data);
105 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
106 gmp_float_imp(gmp_float_imp&& o) BOOST_NOEXCEPT
108 m_data[0] = o.m_data[0];
109 o.m_data[0]._mp_d = 0;
112 gmp_float_imp& operator = (const gmp_float_imp& o)
114 if(m_data[0]._mp_d == 0)
115 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
116 if(o.m_data[0]._mp_d)
117 mpf_set(m_data, o.m_data);
120 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
121 gmp_float_imp& operator = (gmp_float_imp&& o) BOOST_NOEXCEPT
123 mpf_swap(m_data, o.m_data);
128 #ifdef BOOST_HAS_LONG_LONG
129 #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
130 gmp_float_imp& operator = (boost::ulong_long_type i)
132 *this = static_cast<unsigned long>(i);
136 gmp_float_imp& operator = (boost::ulong_long_type i)
138 if(m_data[0]._mp_d == 0)
139 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
140 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
143 mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
144 mpf_set_ui(m_data, 0);
147 mpf_set_ui(t, static_cast<unsigned long>(i & mask));
149 mpf_mul_2exp(t, t, shift);
150 mpf_add(m_data, m_data, t);
151 shift += std::numeric_limits<unsigned long>::digits;
152 i >>= std::numeric_limits<unsigned long>::digits;
158 gmp_float_imp& operator = (boost::long_long_type i)
160 if(m_data[0]._mp_d == 0)
161 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
163 *this = static_cast<boost::ulong_long_type>(boost::multiprecision::detail::unsigned_abs(i));
165 mpf_neg(m_data, m_data);
169 gmp_float_imp& operator = (unsigned long i)
171 if(m_data[0]._mp_d == 0)
172 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
173 mpf_set_ui(m_data, i);
176 gmp_float_imp& operator = (long i)
178 if(m_data[0]._mp_d == 0)
179 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
180 mpf_set_si(m_data, i);
183 gmp_float_imp& operator = (double d)
185 if(m_data[0]._mp_d == 0)
186 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
187 mpf_set_d(m_data, d);
190 gmp_float_imp& operator = (long double a)
196 if(m_data[0]._mp_d == 0)
197 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
200 mpf_set_si(m_data, 0);
205 mpf_set_si(m_data, 1);
209 BOOST_ASSERT(!(boost::math::isinf)(a));
210 BOOST_ASSERT(!(boost::math::isnan)(a));
214 mpf_set_ui(m_data, 0u);
218 static const int shift = std::numeric_limits<int>::digits - 1;
222 // extract int sized bits from f:
226 mpf_mul_2exp(m_data, m_data, shift);
228 mpf_add_ui(m_data, m_data, static_cast<unsigned>(term));
230 mpf_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
234 mpf_mul_2exp(m_data, m_data, e);
236 mpf_div_2exp(m_data, m_data, -e);
239 gmp_float_imp& operator = (const char* s)
241 if(m_data[0]._mp_d == 0)
242 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
243 if(0 != mpf_set_str(m_data, s, 10))
244 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid floating point number.")));
247 void swap(gmp_float_imp& o) BOOST_NOEXCEPT
249 mpf_swap(m_data, o.m_data);
251 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
253 BOOST_ASSERT(m_data[0]._mp_d);
255 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
256 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
257 std::streamsize org_digits(digits);
259 if(scientific && digits)
264 void *(*alloc_func_ptr) (size_t);
265 void *(*realloc_func_ptr) (void *, size_t, size_t);
266 void (*free_func_ptr) (void *, size_t);
267 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
269 if(mpf_sgn(m_data) == 0)
278 char* ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
279 --e; // To match with what our formatter expects.
282 // Oops we actually need a different number of digits to what we asked for:
283 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
287 // We need to get *all* the digits and then possibly round up,
288 // we end up with either "0" or "1" as the result.
289 ps = mpf_get_str (0, &e, 10, 0, m_data);
291 unsigned offset = *ps == '-' ? 1 : 0;
298 else if(ps[offset] == '5')
300 unsigned i = offset + 1;
301 bool round_up = false;
330 ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
331 --e; // To match with what our formatter expects.
335 ps = mpf_get_str (0, &e, 10, 1, m_data);
337 unsigned offset = *ps == '-' ? 1 : 0;
343 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
345 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, mpf_sgn(m_data) == 0);
348 ~gmp_float_imp() BOOST_NOEXCEPT
353 void negate() BOOST_NOEXCEPT
355 BOOST_ASSERT(m_data[0]._mp_d);
356 mpf_neg(m_data, m_data);
358 int compare(const gmp_float<digits10>& o)const BOOST_NOEXCEPT
360 BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
361 return mpf_cmp(m_data, o.m_data);
363 int compare(long i)const BOOST_NOEXCEPT
365 BOOST_ASSERT(m_data[0]._mp_d);
366 return mpf_cmp_si(m_data, i);
368 int compare(unsigned long i)const BOOST_NOEXCEPT
370 BOOST_ASSERT(m_data[0]._mp_d);
371 return mpf_cmp_ui(m_data, i);
374 typename enable_if<is_arithmetic<V>, int>::type compare(V v)const
376 gmp_float<digits10> d;
380 mpf_t& data() BOOST_NOEXCEPT
382 BOOST_ASSERT(m_data[0]._mp_d);
385 const mpf_t& data()const BOOST_NOEXCEPT
387 BOOST_ASSERT(m_data[0]._mp_d);
392 static unsigned& get_default_precision() BOOST_NOEXCEPT
394 static unsigned val = 50;
399 } // namespace detail
404 template <unsigned digits10>
405 struct gmp_float : public detail::gmp_float_imp<digits10>
409 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
411 gmp_float(const gmp_float& o) : detail::gmp_float_imp<digits10>(o) {}
412 template <unsigned D>
413 gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= digits10>::type* = 0);
414 template <unsigned D>
415 explicit gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= digits10>::type* = 0);
416 gmp_float(const gmp_int& o);
417 gmp_float(const gmp_rational& o);
418 gmp_float(const mpf_t val)
420 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
421 mpf_set(this->m_data, val);
423 gmp_float(const mpz_t val)
425 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
426 mpf_set_z(this->m_data, val);
428 gmp_float(const mpq_t val)
430 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
431 mpf_set_q(this->m_data, val);
433 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
434 gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<digits10>(static_cast<detail::gmp_float_imp<digits10>&&>(o)) {}
436 gmp_float& operator=(const gmp_float& o)
438 *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10> const&>(o);
441 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
442 gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT
444 *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10>&&>(o);
448 template <unsigned D>
449 gmp_float& operator=(const gmp_float<D>& o);
450 gmp_float& operator=(const gmp_int& o);
451 gmp_float& operator=(const gmp_rational& o);
452 gmp_float& operator=(const mpf_t val)
454 if(this->m_data[0]._mp_d == 0)
455 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
456 mpf_set(this->m_data, val);
459 gmp_float& operator=(const mpz_t val)
461 if(this->m_data[0]._mp_d == 0)
462 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
463 mpf_set_z(this->m_data, val);
466 gmp_float& operator=(const mpq_t val)
468 if(this->m_data[0]._mp_d == 0)
469 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
470 mpf_set_q(this->m_data, val);
474 gmp_float& operator=(const V& v)
476 *static_cast<detail::gmp_float_imp<digits10>*>(this) = v;
482 struct gmp_float<0> : public detail::gmp_float_imp<0>
486 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
488 gmp_float(const mpf_t val)
490 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
491 mpf_set(this->m_data, val);
493 gmp_float(const mpz_t val)
495 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
496 mpf_set_z(this->m_data, val);
498 gmp_float(const mpq_t val)
500 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
501 mpf_set_q(this->m_data, val);
503 gmp_float(const gmp_float& o) : detail::gmp_float_imp<0>(o) {}
504 template <unsigned D>
505 gmp_float(const gmp_float<D>& o)
507 mpf_init2(this->m_data, mpf_get_prec(o.data()));
508 mpf_set(this->m_data, o.data());
510 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
511 gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<0>(static_cast<detail::gmp_float_imp<0>&&>(o)) {}
513 gmp_float(const gmp_int& o);
514 gmp_float(const gmp_rational& o);
515 gmp_float(const gmp_float& o, unsigned digits10)
517 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
518 mpf_set(this->m_data, o.data());
521 gmp_float& operator=(const gmp_float& o)
523 *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> const&>(o);
526 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
527 gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT
529 *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> &&>(o);
533 template <unsigned D>
534 gmp_float& operator=(const gmp_float<D>& o)
536 if(this->m_data[0]._mp_d == 0)
538 mpf_init2(this->m_data, mpf_get_prec(o.data()));
542 mpf_set_prec(this->m_data, mpf_get_prec(o.data()));
544 mpf_set(this->m_data, o.data());
547 gmp_float& operator=(const gmp_int& o);
548 gmp_float& operator=(const gmp_rational& o);
549 gmp_float& operator=(const mpf_t val)
551 if(this->m_data[0]._mp_d == 0)
552 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
553 mpf_set(this->m_data, val);
556 gmp_float& operator=(const mpz_t val)
558 if(this->m_data[0]._mp_d == 0)
559 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
560 mpf_set_z(this->m_data, val);
563 gmp_float& operator=(const mpq_t val)
565 if(this->m_data[0]._mp_d == 0)
566 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
567 mpf_set_q(this->m_data, val);
571 gmp_float& operator=(const V& v)
573 *static_cast<detail::gmp_float_imp<0>*>(this) = v;
576 static unsigned default_precision() BOOST_NOEXCEPT
578 return get_default_precision();
580 static void default_precision(unsigned v) BOOST_NOEXCEPT
582 get_default_precision() = v;
584 unsigned precision()const BOOST_NOEXCEPT
586 return static_cast<unsigned>(multiprecision::detail::digits2_2_10(static_cast<unsigned long>(mpf_get_prec(this->m_data))));
588 void precision(unsigned digits10) BOOST_NOEXCEPT
590 mpf_set_prec(this->m_data, multiprecision::detail::digits10_2_2(digits10));
594 template <unsigned digits10, class T>
595 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_eq(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
597 return a.compare(b) == 0;
599 template <unsigned digits10, class T>
600 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_lt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
602 return a.compare(b) < 0;
604 template <unsigned digits10, class T>
605 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_gt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
607 return a.compare(b) > 0;
610 template <unsigned D1, unsigned D2>
611 inline void eval_add(gmp_float<D1>& result, const gmp_float<D2>& o)
613 mpf_add(result.data(), result.data(), o.data());
615 template <unsigned D1, unsigned D2>
616 inline void eval_subtract(gmp_float<D1>& result, const gmp_float<D2>& o)
618 mpf_sub(result.data(), result.data(), o.data());
620 template <unsigned D1, unsigned D2>
621 inline void eval_multiply(gmp_float<D1>& result, const gmp_float<D2>& o)
623 mpf_mul(result.data(), result.data(), o.data());
625 template <unsigned digits10>
626 inline bool eval_is_zero(const gmp_float<digits10>& val) BOOST_NOEXCEPT
628 return mpf_sgn(val.data()) == 0;
630 template <unsigned D1, unsigned D2>
631 inline void eval_divide(gmp_float<D1>& result, const gmp_float<D2>& o)
634 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
635 mpf_div(result.data(), result.data(), o.data());
637 template <unsigned digits10>
638 inline void eval_add(gmp_float<digits10>& result, unsigned long i)
640 mpf_add_ui(result.data(), result.data(), i);
642 template <unsigned digits10>
643 inline void eval_subtract(gmp_float<digits10>& result, unsigned long i)
645 mpf_sub_ui(result.data(), result.data(), i);
647 template <unsigned digits10>
648 inline void eval_multiply(gmp_float<digits10>& result, unsigned long i)
650 mpf_mul_ui(result.data(), result.data(), i);
652 template <unsigned digits10>
653 inline void eval_divide(gmp_float<digits10>& result, unsigned long i)
656 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
657 mpf_div_ui(result.data(), result.data(), i);
659 template <unsigned digits10>
660 inline void eval_add(gmp_float<digits10>& result, long i)
663 mpf_add_ui(result.data(), result.data(), i);
665 mpf_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
667 template <unsigned digits10>
668 inline void eval_subtract(gmp_float<digits10>& result, long i)
671 mpf_sub_ui(result.data(), result.data(), i);
673 mpf_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
675 template <unsigned digits10>
676 inline void eval_multiply(gmp_float<digits10>& result, long i)
678 mpf_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
680 mpf_neg(result.data(), result.data());
682 template <unsigned digits10>
683 inline void eval_divide(gmp_float<digits10>& result, long i)
686 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
687 mpf_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
689 mpf_neg(result.data(), result.data());
692 // Specialised 3 arg versions of the basic operators:
694 template <unsigned D1, unsigned D2, unsigned D3>
695 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
697 mpf_add(a.data(), x.data(), y.data());
699 template <unsigned D1, unsigned D2>
700 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
702 mpf_add_ui(a.data(), x.data(), y);
704 template <unsigned D1, unsigned D2>
705 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
708 mpf_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
710 mpf_add_ui(a.data(), x.data(), y);
712 template <unsigned D1, unsigned D2>
713 inline void eval_add(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
715 mpf_add_ui(a.data(), y.data(), x);
717 template <unsigned D1, unsigned D2>
718 inline void eval_add(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
722 mpf_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
723 mpf_neg(a.data(), a.data());
726 mpf_add_ui(a.data(), y.data(), x);
728 template <unsigned D1, unsigned D2, unsigned D3>
729 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
731 mpf_sub(a.data(), x.data(), y.data());
733 template <unsigned D1, unsigned D2>
734 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
736 mpf_sub_ui(a.data(), x.data(), y);
738 template <unsigned D1, unsigned D2>
739 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
742 mpf_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
744 mpf_sub_ui(a.data(), x.data(), y);
746 template <unsigned D1, unsigned D2>
747 inline void eval_subtract(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
749 mpf_ui_sub(a.data(), x, y.data());
751 template <unsigned D1, unsigned D2>
752 inline void eval_subtract(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
756 mpf_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
757 mpf_neg(a.data(), a.data());
760 mpf_ui_sub(a.data(), x, y.data());
763 template <unsigned D1, unsigned D2, unsigned D3>
764 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
766 mpf_mul(a.data(), x.data(), y.data());
768 template <unsigned D1, unsigned D2>
769 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
771 mpf_mul_ui(a.data(), x.data(), y);
773 template <unsigned D1, unsigned D2>
774 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
778 mpf_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
782 mpf_mul_ui(a.data(), x.data(), y);
784 template <unsigned D1, unsigned D2>
785 inline void eval_multiply(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
787 mpf_mul_ui(a.data(), y.data(), x);
789 template <unsigned D1, unsigned D2>
790 inline void eval_multiply(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
794 mpf_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
795 mpf_neg(a.data(), a.data());
798 mpf_mul_ui(a.data(), y.data(), x);
801 template <unsigned D1, unsigned D2, unsigned D3>
802 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
805 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
806 mpf_div(a.data(), x.data(), y.data());
808 template <unsigned D1, unsigned D2>
809 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
812 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
813 mpf_div_ui(a.data(), x.data(), y);
815 template <unsigned D1, unsigned D2>
816 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
819 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
822 mpf_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
826 mpf_div_ui(a.data(), x.data(), y);
828 template <unsigned D1, unsigned D2>
829 inline void eval_divide(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
832 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
833 mpf_ui_div(a.data(), x, y.data());
835 template <unsigned D1, unsigned D2>
836 inline void eval_divide(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
839 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
842 mpf_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
843 mpf_neg(a.data(), a.data());
846 mpf_ui_div(a.data(), x, y.data());
849 template <unsigned digits10>
850 inline int eval_get_sign(const gmp_float<digits10>& val) BOOST_NOEXCEPT
852 return mpf_sgn(val.data());
855 template <unsigned digits10>
856 inline void eval_convert_to(unsigned long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
858 if(0 == mpf_fits_ulong_p(val.data()))
859 *result = (std::numeric_limits<unsigned long>::max)();
861 *result = mpf_get_ui(val.data());
863 template <unsigned digits10>
864 inline void eval_convert_to(long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
866 if(0 == mpf_fits_slong_p(val.data()))
868 *result = (std::numeric_limits<unsigned long>::max)();
869 *result *= mpf_sgn(val.data());
872 *result = mpf_get_si(val.data());
874 template <unsigned digits10>
875 inline void eval_convert_to(double* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
877 *result = mpf_get_d(val.data());
879 #ifdef BOOST_HAS_LONG_LONG
880 template <unsigned digits10>
881 inline void eval_convert_to(boost::long_long_type* result, const gmp_float<digits10>& val)
883 gmp_float<digits10> t(val);
884 if(eval_get_sign(t) < 0)
887 long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits;
890 mpf_div_2exp(t.data(), t.data(), digits);
892 if(!mpf_fits_slong_p(t.data()))
894 if(eval_get_sign(val) < 0)
895 *result = (std::numeric_limits<boost::long_long_type>::min)();
897 *result = (std::numeric_limits<boost::long_long_type>::max)();
901 *result = mpf_get_si(t.data());
905 digits -= std::numeric_limits<unsigned long>::digits;
906 mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
907 unsigned long l = mpf_get_ui(t.data());
912 if(eval_get_sign(val) < 0)
915 template <unsigned digits10>
916 inline void eval_convert_to(boost::ulong_long_type* result, const gmp_float<digits10>& val)
918 gmp_float<digits10> t(val);
920 long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits;
923 mpf_div_2exp(t.data(), t.data(), digits);
925 if(!mpf_fits_ulong_p(t.data()))
927 *result = (std::numeric_limits<boost::long_long_type>::max)();
931 *result = mpf_get_ui(t.data());
935 digits -= std::numeric_limits<unsigned long>::digits;
936 mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
937 unsigned long l = mpf_get_ui(t.data());
946 // Native non-member operations:
948 template <unsigned Digits10>
949 inline void eval_sqrt(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
951 mpf_sqrt(result.data(), val.data());
954 template <unsigned Digits10>
955 inline void eval_abs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
957 mpf_abs(result.data(), val.data());
960 template <unsigned Digits10>
961 inline void eval_fabs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
963 mpf_abs(result.data(), val.data());
965 template <unsigned Digits10>
966 inline void eval_ceil(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
968 mpf_ceil(result.data(), val.data());
970 template <unsigned Digits10>
971 inline void eval_floor(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
973 mpf_floor(result.data(), val.data());
975 template <unsigned Digits10>
976 inline void eval_trunc(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
978 mpf_trunc(result.data(), val.data());
980 template <unsigned Digits10>
981 inline void eval_ldexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long e)
984 mpf_mul_2exp(result.data(), val.data(), e);
986 mpf_div_2exp(result.data(), val.data(), -e);
990 template <unsigned Digits10>
991 inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, int* e)
993 #if BOOST_MP_MPIR_VERSION >= 20600
995 mpf_get_d_2exp(&v, val.data());
998 mpf_get_d_2exp(&v, val.data());
1001 eval_ldexp(result, val, -v);
1003 template <unsigned Digits10>
1004 inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long* e)
1006 #if BOOST_MP_MPIR_VERSION >= 20600
1008 mpf_get_d_2exp(&v, val.data());
1010 eval_ldexp(result, val, -v);
1012 mpf_get_d_2exp(e, val.data());
1013 eval_ldexp(result, val, -*e);
1017 template <unsigned Digits10>
1018 inline std::size_t hash_value(const gmp_float<Digits10>& val)
1020 std::size_t result = 0;
1021 for(int i = 0; i < std::abs(val.data()[0]._mp_size); ++i)
1022 boost::hash_combine(result, val.data()[0]._mp_d[i]);
1023 boost::hash_combine(result, val.data()[0]._mp_exp);
1024 boost::hash_combine(result, val.data()[0]._mp_size);
1030 #ifdef BOOST_HAS_LONG_LONG
1031 typedef mpl::list<long, boost::long_long_type> signed_types;
1032 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
1034 typedef mpl::list<long> signed_types;
1035 typedef mpl::list<unsigned long> unsigned_types;
1037 typedef mpl::list<double, long double> float_types;
1041 mpz_init(this->m_data);
1043 gmp_int(const gmp_int& o)
1045 if(o.m_data[0]._mp_d)
1046 mpz_init_set(m_data, o.m_data);
1048 mpz_init(this->m_data);
1050 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1051 gmp_int(gmp_int&& o) BOOST_NOEXCEPT
1053 m_data[0] = o.m_data[0];
1054 o.m_data[0]._mp_d = 0;
1057 explicit gmp_int(const mpf_t val)
1059 mpz_init(this->m_data);
1060 mpz_set_f(this->m_data, val);
1062 gmp_int(const mpz_t val)
1064 mpz_init_set(this->m_data, val);
1066 explicit gmp_int(const mpq_t val)
1068 mpz_init(this->m_data);
1069 mpz_set_q(this->m_data, val);
1071 template <unsigned Digits10>
1072 explicit gmp_int(const gmp_float<Digits10>& o)
1074 mpz_init(this->m_data);
1075 mpz_set_f(this->m_data, o.data());
1077 explicit gmp_int(const gmp_rational& o);
1078 gmp_int& operator = (const gmp_int& o)
1080 if(m_data[0]._mp_d == 0)
1081 mpz_init(this->m_data);
1082 mpz_set(m_data, o.m_data);
1085 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1086 gmp_int& operator = (gmp_int&& o) BOOST_NOEXCEPT
1088 mpz_swap(m_data, o.m_data);
1092 #ifdef BOOST_HAS_LONG_LONG
1093 #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
1094 gmp_int& operator = (boost::ulong_long_type i)
1096 *this = static_cast<unsigned long>(i);
1100 gmp_int& operator = (boost::ulong_long_type i)
1102 if(m_data[0]._mp_d == 0)
1103 mpz_init(this->m_data);
1104 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
1107 mpz_set_ui(m_data, 0);
1108 mpz_init_set_ui(t, 0);
1111 mpz_set_ui(t, static_cast<unsigned long>(i & mask));
1113 mpz_mul_2exp(t, t, shift);
1114 mpz_add(m_data, m_data, t);
1115 shift += std::numeric_limits<unsigned long>::digits;
1116 i >>= std::numeric_limits<unsigned long>::digits;
1122 gmp_int& operator = (boost::long_long_type i)
1124 if(m_data[0]._mp_d == 0)
1125 mpz_init(this->m_data);
1127 *this = boost::multiprecision::detail::unsigned_abs(i);
1129 mpz_neg(m_data, m_data);
1133 gmp_int& operator = (unsigned long i)
1135 if(m_data[0]._mp_d == 0)
1136 mpz_init(this->m_data);
1137 mpz_set_ui(m_data, i);
1140 gmp_int& operator = (long i)
1142 if(m_data[0]._mp_d == 0)
1143 mpz_init(this->m_data);
1144 mpz_set_si(m_data, i);
1147 gmp_int& operator = (double d)
1149 if(m_data[0]._mp_d == 0)
1150 mpz_init(this->m_data);
1151 mpz_set_d(m_data, d);
1154 gmp_int& operator = (long double a)
1160 if(m_data[0]._mp_d == 0)
1161 mpz_init(this->m_data);
1164 mpz_set_si(m_data, 0);
1169 mpz_set_si(m_data, 1);
1173 BOOST_ASSERT(!(boost::math::isinf)(a));
1174 BOOST_ASSERT(!(boost::math::isnan)(a));
1177 long double f, term;
1178 mpz_set_ui(m_data, 0u);
1182 static const int shift = std::numeric_limits<int>::digits - 1;
1186 // extract int sized bits from f:
1187 f = ldexp(f, shift);
1190 mpz_mul_2exp(m_data, m_data, shift);
1192 mpz_add_ui(m_data, m_data, static_cast<unsigned>(term));
1194 mpz_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
1198 mpz_mul_2exp(m_data, m_data, e);
1200 mpz_div_2exp(m_data, m_data, -e);
1203 gmp_int& operator = (const char* s)
1205 if(m_data[0]._mp_d == 0)
1206 mpz_init(this->m_data);
1207 std::size_t n = s ? std::strlen(s) : 0;
1209 if(n && (*s == '0'))
1211 if((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
1225 if(0 != mpz_set_str(m_data, s, radix))
1226 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid integer.")));
1229 mpz_set_ui(m_data, 0);
1232 gmp_int& operator=(const mpf_t val)
1234 if(m_data[0]._mp_d == 0)
1235 mpz_init(this->m_data);
1236 mpz_set_f(this->m_data, val);
1239 gmp_int& operator=(const mpz_t val)
1241 if(m_data[0]._mp_d == 0)
1242 mpz_init(this->m_data);
1243 mpz_set(this->m_data, val);
1246 gmp_int& operator=(const mpq_t val)
1248 if(m_data[0]._mp_d == 0)
1249 mpz_init(this->m_data);
1250 mpz_set_q(this->m_data, val);
1253 template <unsigned Digits10>
1254 gmp_int& operator=(const gmp_float<Digits10>& o)
1256 if(m_data[0]._mp_d == 0)
1257 mpz_init(this->m_data);
1258 mpz_set_f(this->m_data, o.data());
1261 gmp_int& operator=(const gmp_rational& o);
1262 void swap(gmp_int& o)
1264 mpz_swap(m_data, o.m_data);
1266 std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
1268 BOOST_ASSERT(m_data[0]._mp_d);
1271 if((f & std::ios_base::oct) == std::ios_base::oct)
1273 else if((f & std::ios_base::hex) == std::ios_base::hex)
1276 // sanity check, bases 8 and 16 are only available for positive numbers:
1278 if((base != 10) && (mpz_sgn(m_data) < 0))
1279 BOOST_THROW_EXCEPTION(std::runtime_error("Formatted output in bases 8 or 16 is only available for positive numbers"));
1280 void *(*alloc_func_ptr) (size_t);
1281 void *(*realloc_func_ptr) (void *, size_t, size_t);
1282 void (*free_func_ptr) (void *, size_t);
1283 const char* ps = mpz_get_str (0, base, m_data);
1285 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
1286 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
1288 if((base != 10) && (f & std::ios_base::showbase))
1290 int pos = s[0] == '-' ? 1 : 0;
1291 const char* pp = base == 8 ? "0" : "0x";
1292 s.insert(static_cast<std::string::size_type>(pos), pp);
1294 if((f & std::ios_base::showpos) && (s[0] != '-'))
1295 s.insert(static_cast<std::string::size_type>(0), 1, '+');
1299 ~gmp_int() BOOST_NOEXCEPT
1304 void negate() BOOST_NOEXCEPT
1306 BOOST_ASSERT(m_data[0]._mp_d);
1307 mpz_neg(m_data, m_data);
1309 int compare(const gmp_int& o)const BOOST_NOEXCEPT
1311 BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
1312 return mpz_cmp(m_data, o.m_data);
1314 int compare(long i)const BOOST_NOEXCEPT
1316 BOOST_ASSERT(m_data[0]._mp_d);
1317 return mpz_cmp_si(m_data, i);
1319 int compare(unsigned long i)const BOOST_NOEXCEPT
1321 BOOST_ASSERT(m_data[0]._mp_d);
1322 return mpz_cmp_ui(m_data, i);
1325 int compare(V v)const
1331 mpz_t& data() BOOST_NOEXCEPT
1333 BOOST_ASSERT(m_data[0]._mp_d);
1336 const mpz_t& data()const BOOST_NOEXCEPT
1338 BOOST_ASSERT(m_data[0]._mp_d);
1346 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const gmp_int& a, const T& b)
1348 return a.compare(b) == 0;
1351 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const gmp_int& a, const T& b)
1353 return a.compare(b) < 0;
1356 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const gmp_int& a, const T& b)
1358 return a.compare(b) > 0;
1361 inline bool eval_is_zero(const gmp_int& val)
1363 return mpz_sgn(val.data()) == 0;
1365 inline void eval_add(gmp_int& t, const gmp_int& o)
1367 mpz_add(t.data(), t.data(), o.data());
1369 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, const gmp_int& b)
1371 mpz_addmul(t.data(), a.data(), b.data());
1373 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, const gmp_int& b)
1375 mpz_submul(t.data(), a.data(), b.data());
1377 inline void eval_subtract(gmp_int& t, const gmp_int& o)
1379 mpz_sub(t.data(), t.data(), o.data());
1381 inline void eval_multiply(gmp_int& t, const gmp_int& o)
1383 mpz_mul(t.data(), t.data(), o.data());
1385 inline void eval_divide(gmp_int& t, const gmp_int& o)
1388 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1389 mpz_tdiv_q(t.data(), t.data(), o.data());
1391 inline void eval_modulus(gmp_int& t, const gmp_int& o)
1393 mpz_tdiv_r(t.data(), t.data(), o.data());
1395 inline void eval_add(gmp_int& t, unsigned long i)
1397 mpz_add_ui(t.data(), t.data(), i);
1399 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, unsigned long i)
1401 mpz_addmul_ui(t.data(), a.data(), i);
1403 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, unsigned long i)
1405 mpz_submul_ui(t.data(), a.data(), i);
1407 inline void eval_subtract(gmp_int& t, unsigned long i)
1409 mpz_sub_ui(t.data(), t.data(), i);
1411 inline void eval_multiply(gmp_int& t, unsigned long i)
1413 mpz_mul_ui(t.data(), t.data(), i);
1415 inline void eval_modulus(gmp_int& t, unsigned long i)
1417 mpz_tdiv_r_ui(t.data(), t.data(), i);
1419 inline void eval_divide(gmp_int& t, unsigned long i)
1422 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1423 mpz_tdiv_q_ui(t.data(), t.data(), i);
1425 inline void eval_add(gmp_int& t, long i)
1428 mpz_add_ui(t.data(), t.data(), i);
1430 mpz_sub_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1432 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, long i)
1435 mpz_addmul_ui(t.data(), a.data(), i);
1437 mpz_submul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i));
1439 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, long i)
1442 mpz_submul_ui(t.data(), a.data(), i);
1444 mpz_addmul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i));
1446 inline void eval_subtract(gmp_int& t, long i)
1449 mpz_sub_ui(t.data(), t.data(), i);
1451 mpz_add_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1453 inline void eval_multiply(gmp_int& t, long i)
1455 mpz_mul_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1457 mpz_neg(t.data(), t.data());
1459 inline void eval_modulus(gmp_int& t, long i)
1461 mpz_tdiv_r_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1463 inline void eval_divide(gmp_int& t, long i)
1466 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1467 mpz_tdiv_q_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1469 mpz_neg(t.data(), t.data());
1472 inline void eval_left_shift(gmp_int& t, UI i)
1474 mpz_mul_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
1477 inline void eval_right_shift(gmp_int& t, UI i)
1479 mpz_fdiv_q_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
1482 inline void eval_left_shift(gmp_int& t, const gmp_int& v, UI i)
1484 mpz_mul_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
1487 inline void eval_right_shift(gmp_int& t, const gmp_int& v, UI i)
1489 mpz_fdiv_q_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
1492 inline void eval_bitwise_and(gmp_int& result, const gmp_int& v)
1494 mpz_and(result.data(), result.data(), v.data());
1497 inline void eval_bitwise_or(gmp_int& result, const gmp_int& v)
1499 mpz_ior(result.data(), result.data(), v.data());
1502 inline void eval_bitwise_xor(gmp_int& result, const gmp_int& v)
1504 mpz_xor(result.data(), result.data(), v.data());
1507 inline void eval_add(gmp_int& t, const gmp_int& p, const gmp_int& o)
1509 mpz_add(t.data(), p.data(), o.data());
1511 inline void eval_subtract(gmp_int& t, const gmp_int& p, const gmp_int& o)
1513 mpz_sub(t.data(), p.data(), o.data());
1515 inline void eval_multiply(gmp_int& t, const gmp_int& p, const gmp_int& o)
1517 mpz_mul(t.data(), p.data(), o.data());
1519 inline void eval_divide(gmp_int& t, const gmp_int& p, const gmp_int& o)
1522 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1523 mpz_tdiv_q(t.data(), p.data(), o.data());
1525 inline void eval_modulus(gmp_int& t, const gmp_int& p, const gmp_int& o)
1527 mpz_tdiv_r(t.data(), p.data(), o.data());
1529 inline void eval_add(gmp_int& t, const gmp_int& p, unsigned long i)
1531 mpz_add_ui(t.data(), p.data(), i);
1533 inline void eval_subtract(gmp_int& t, const gmp_int& p, unsigned long i)
1535 mpz_sub_ui(t.data(), p.data(), i);
1537 inline void eval_multiply(gmp_int& t, const gmp_int& p, unsigned long i)
1539 mpz_mul_ui(t.data(), p.data(), i);
1541 inline void eval_modulus(gmp_int& t, const gmp_int& p, unsigned long i)
1543 mpz_tdiv_r_ui(t.data(), p.data(), i);
1545 inline void eval_divide(gmp_int& t, const gmp_int& p, unsigned long i)
1548 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1549 mpz_tdiv_q_ui(t.data(), p.data(), i);
1551 inline void eval_add(gmp_int& t, const gmp_int& p, long i)
1554 mpz_add_ui(t.data(), p.data(), i);
1556 mpz_sub_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1558 inline void eval_subtract(gmp_int& t, const gmp_int& p, long i)
1561 mpz_sub_ui(t.data(), p.data(), i);
1563 mpz_add_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1565 inline void eval_multiply(gmp_int& t, const gmp_int& p, long i)
1567 mpz_mul_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1569 mpz_neg(t.data(), t.data());
1571 inline void eval_modulus(gmp_int& t, const gmp_int& p, long i)
1573 mpz_tdiv_r_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1575 inline void eval_divide(gmp_int& t, const gmp_int& p, long i)
1578 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1579 mpz_tdiv_q_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1581 mpz_neg(t.data(), t.data());
1584 inline void eval_bitwise_and(gmp_int& result, const gmp_int& u, const gmp_int& v)
1586 mpz_and(result.data(), u.data(), v.data());
1589 inline void eval_bitwise_or(gmp_int& result, const gmp_int& u, const gmp_int& v)
1591 mpz_ior(result.data(), u.data(), v.data());
1594 inline void eval_bitwise_xor(gmp_int& result, const gmp_int& u, const gmp_int& v)
1596 mpz_xor(result.data(), u.data(), v.data());
1599 inline void eval_complement(gmp_int& result, const gmp_int& u)
1601 mpz_com(result.data(), u.data());
1604 inline int eval_get_sign(const gmp_int& val)
1606 return mpz_sgn(val.data());
1608 inline void eval_convert_to(unsigned long* result, const gmp_int& val)
1610 if(0 == mpz_fits_ulong_p(val.data()))
1612 *result = (std::numeric_limits<unsigned long>::max)();
1615 *result = mpz_get_ui(val.data());
1617 inline void eval_convert_to(long* result, const gmp_int& val)
1619 if(0 == mpz_fits_slong_p(val.data()))
1621 *result = (std::numeric_limits<unsigned long>::max)();
1622 *result *= mpz_sgn(val.data());
1625 *result = mpz_get_si(val.data());
1627 inline void eval_convert_to(double* result, const gmp_int& val)
1629 *result = mpz_get_d(val.data());
1632 inline void eval_abs(gmp_int& result, const gmp_int& val)
1634 mpz_abs(result.data(), val.data());
1637 inline void eval_gcd(gmp_int& result, const gmp_int& a, const gmp_int& b)
1639 mpz_gcd(result.data(), a.data(), b.data());
1641 inline void eval_lcm(gmp_int& result, const gmp_int& a, const gmp_int& b)
1643 mpz_lcm(result.data(), a.data(), b.data());
1646 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)
1648 mpz_gcd_ui(result.data(), a.data(), b);
1651 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)
1653 mpz_lcm_ui(result.data(), a.data(), b);
1656 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)
1658 mpz_gcd_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b));
1661 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)
1663 mpz_lcm_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b));
1666 inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x)
1668 mpz_sqrtrem(s.data(), r.data(), x.data());
1671 inline unsigned eval_lsb(const gmp_int& val)
1673 int c = eval_get_sign(val);
1676 BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
1680 BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
1682 return static_cast<unsigned>(mpz_scan1(val.data(), 0));
1685 inline unsigned eval_msb(const gmp_int& val)
1687 int c = eval_get_sign(val);
1690 BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
1694 BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
1696 return static_cast<unsigned>(mpz_sizeinbase(val.data(), 2) - 1);
1699 inline bool eval_bit_test(const gmp_int& val, unsigned index)
1701 return mpz_tstbit(val.data(), index) ? true : false;
1704 inline void eval_bit_set(gmp_int& val, unsigned index)
1706 mpz_setbit(val.data(), index);
1709 inline void eval_bit_unset(gmp_int& val, unsigned index)
1711 mpz_clrbit(val.data(), index);
1714 inline void eval_bit_flip(gmp_int& val, unsigned index)
1716 mpz_combit(val.data(), index);
1719 inline void eval_qr(const gmp_int& x, const gmp_int& y,
1720 gmp_int& q, gmp_int& r)
1722 mpz_tdiv_qr(q.data(), r.data(), x.data(), y.data());
1725 template <class Integer>
1726 inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
1728 if((sizeof(Integer) <= sizeof(long)) || (val <= (std::numeric_limits<unsigned long>::max)()))
1730 return mpz_tdiv_ui(x.data(), val);
1734 return default_ops::eval_integer_modulus(x, val);
1737 template <class Integer>
1738 inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
1740 return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val));
1742 inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m)
1744 if(eval_get_sign(p) < 0)
1746 BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
1748 mpz_powm(result.data(), base.data(), p.data(), m.data());
1751 template <class Integer>
1752 inline typename enable_if<
1754 is_unsigned<Integer>,
1755 mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)>
1757 >::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
1759 mpz_powm_ui(result.data(), base.data(), p, m.data());
1761 template <class Integer>
1762 inline typename enable_if<
1765 mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)>
1767 >::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
1771 BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
1773 mpz_powm_ui(result.data(), base.data(), p, m.data());
1776 inline std::size_t hash_value(const gmp_int& val)
1778 // We should really use mpz_limbs_read here, but that's unsupported on older versions:
1779 std::size_t result = 0;
1780 for(int i = 0; i < std::abs(val.data()[0]._mp_size); ++i)
1781 boost::hash_combine(result, val.data()[0]._mp_d[i]);
1782 boost::hash_combine(result, val.data()[0]._mp_size);
1786 struct gmp_rational;
1787 void eval_add(gmp_rational& t, const gmp_rational& o);
1791 #ifdef BOOST_HAS_LONG_LONG
1792 typedef mpl::list<long, boost::long_long_type> signed_types;
1793 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
1795 typedef mpl::list<long> signed_types;
1796 typedef mpl::list<unsigned long> unsigned_types;
1798 typedef mpl::list<double, long double> float_types;
1802 mpq_init(this->m_data);
1804 gmp_rational(const gmp_rational& o)
1807 if(o.m_data[0]._mp_num._mp_d)
1808 mpq_set(m_data, o.m_data);
1810 gmp_rational(const gmp_int& o)
1813 mpq_set_z(m_data, o.data());
1815 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1816 gmp_rational(gmp_rational&& o) BOOST_NOEXCEPT
1818 m_data[0] = o.m_data[0];
1819 o.m_data[0]._mp_num._mp_d = 0;
1820 o.m_data[0]._mp_den._mp_d = 0;
1823 gmp_rational(const mpq_t o)
1828 gmp_rational(const mpz_t o)
1831 mpq_set_z(m_data, o);
1833 gmp_rational& operator = (const gmp_rational& o)
1835 if(m_data[0]._mp_den._mp_d == 0)
1837 mpq_set(m_data, o.m_data);
1840 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1841 gmp_rational& operator = (gmp_rational&& o) BOOST_NOEXCEPT
1843 mpq_swap(m_data, o.m_data);
1847 #ifdef BOOST_HAS_LONG_LONG
1848 #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
1849 gmp_rational& operator = (boost::ulong_long_type i)
1851 *this = static_cast<unsigned long>(i);
1855 gmp_rational& operator = (boost::ulong_long_type i)
1857 if(m_data[0]._mp_den._mp_d == 0)
1861 mpq_set_z(m_data, zi.data());
1864 gmp_rational& operator = (boost::long_long_type i)
1866 if(m_data[0]._mp_den._mp_d == 0)
1869 *this = boost::multiprecision::detail::unsigned_abs(i);
1871 mpq_neg(m_data, m_data);
1876 gmp_rational& operator = (unsigned long i)
1878 if(m_data[0]._mp_den._mp_d == 0)
1880 mpq_set_ui(m_data, i, 1);
1883 gmp_rational& operator = (long i)
1885 if(m_data[0]._mp_den._mp_d == 0)
1887 mpq_set_si(m_data, i, 1);
1890 gmp_rational& operator = (double d)
1892 if(m_data[0]._mp_den._mp_d == 0)
1894 mpq_set_d(m_data, d);
1897 gmp_rational& operator = (long double a)
1902 using default_ops::eval_add;
1903 using default_ops::eval_subtract;
1905 if(m_data[0]._mp_den._mp_d == 0)
1909 mpq_set_si(m_data, 0, 1);
1914 mpq_set_si(m_data, 1, 1);
1918 BOOST_ASSERT(!(boost::math::isinf)(a));
1919 BOOST_ASSERT(!(boost::math::isnan)(a));
1922 long double f, term;
1923 mpq_set_ui(m_data, 0, 1);
1924 mpq_set_ui(m_data, 0u, 1);
1929 static const int shift = std::numeric_limits<int>::digits - 1;
1933 // extract int sized bits from f:
1934 f = ldexp(f, shift);
1937 mpq_mul_2exp(m_data, m_data, shift);
1938 t = static_cast<long>(term);
1943 mpq_mul_2exp(m_data, m_data, e);
1945 mpq_div_2exp(m_data, m_data, -e);
1948 gmp_rational& operator = (const char* s)
1950 if(m_data[0]._mp_den._mp_d == 0)
1952 if(0 != mpq_set_str(m_data, s, 10))
1953 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid rational number.")));
1956 gmp_rational& operator=(const gmp_int& o)
1958 if(m_data[0]._mp_den._mp_d == 0)
1960 mpq_set_z(m_data, o.data());
1963 gmp_rational& operator=(const mpq_t o)
1965 if(m_data[0]._mp_den._mp_d == 0)
1970 gmp_rational& operator=(const mpz_t o)
1972 if(m_data[0]._mp_den._mp_d == 0)
1974 mpq_set_z(m_data, o);
1977 void swap(gmp_rational& o)
1979 mpq_swap(m_data, o.m_data);
1981 std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags /*f*/)const
1983 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
1984 // TODO make a better job of this including handling of f!!
1985 void *(*alloc_func_ptr) (size_t);
1986 void *(*realloc_func_ptr) (void *, size_t, size_t);
1987 void (*free_func_ptr) (void *, size_t);
1988 const char* ps = mpq_get_str (0, 10, m_data);
1990 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
1991 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
1996 if(m_data[0]._mp_num._mp_d || m_data[0]._mp_den._mp_d)
2001 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2002 mpq_neg(m_data, m_data);
2004 int compare(const gmp_rational& o)const
2006 BOOST_ASSERT(m_data[0]._mp_num._mp_d && o.m_data[0]._mp_num._mp_d);
2007 return mpq_cmp(m_data, o.m_data);
2010 int compare(V v)const
2016 int compare(unsigned long v)const
2018 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2019 return mpq_cmp_ui(m_data, v, 1);
2021 int compare(long v)const
2023 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2024 return mpq_cmp_si(m_data, v, 1);
2028 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2031 const mpq_t& data()const
2033 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2040 inline bool eval_is_zero(const gmp_rational& val)
2042 return mpq_sgn(val.data()) == 0;
2045 inline bool eval_eq(gmp_rational& a, const T& b)
2047 return a.compare(b) == 0;
2050 inline bool eval_lt(gmp_rational& a, const T& b)
2052 return a.compare(b) < 0;
2055 inline bool eval_gt(gmp_rational& a, const T& b)
2057 return a.compare(b) > 0;
2060 inline void eval_add(gmp_rational& t, const gmp_rational& o)
2062 mpq_add(t.data(), t.data(), o.data());
2064 inline void eval_subtract(gmp_rational& t, const gmp_rational& o)
2066 mpq_sub(t.data(), t.data(), o.data());
2068 inline void eval_multiply(gmp_rational& t, const gmp_rational& o)
2070 mpq_mul(t.data(), t.data(), o.data());
2072 inline void eval_divide(gmp_rational& t, const gmp_rational& o)
2075 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
2076 mpq_div(t.data(), t.data(), o.data());
2078 inline void eval_add(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
2080 mpq_add(t.data(), p.data(), o.data());
2082 inline void eval_subtract(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
2084 mpq_sub(t.data(), p.data(), o.data());
2086 inline void eval_multiply(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
2088 mpq_mul(t.data(), p.data(), o.data());
2090 inline void eval_divide(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
2093 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
2094 mpq_div(t.data(), p.data(), o.data());
2097 inline int eval_get_sign(const gmp_rational& val)
2099 return mpq_sgn(val.data());
2101 inline void eval_convert_to(double* result, const gmp_rational& val)
2104 // This does not round correctly:
2106 //*result = mpq_get_d(val.data());
2110 boost::multiprecision::detail::generic_convert_rational_to_float(*result, val);
2113 inline void eval_convert_to(long* result, const gmp_rational& val)
2116 eval_convert_to(&r, val);
2117 *result = static_cast<long>(r);
2120 inline void eval_convert_to(unsigned long* result, const gmp_rational& val)
2123 eval_convert_to(&r, val);
2124 *result = static_cast<long>(r);
2127 inline void eval_abs(gmp_rational& result, const gmp_rational& val)
2129 mpq_abs(result.data(), val.data());
2132 inline void assign_components(gmp_rational& result, unsigned long v1, unsigned long v2)
2134 mpq_set_ui(result.data(), v1, v2);
2135 mpq_canonicalize(result.data());
2137 inline void assign_components(gmp_rational& result, long v1, long v2)
2139 mpq_set_si(result.data(), v1, v2);
2140 mpq_canonicalize(result.data());
2142 inline void assign_components(gmp_rational& result, gmp_int const& v1, gmp_int const& v2)
2144 mpz_set(mpq_numref(result.data()), v1.data());
2145 mpz_set(mpq_denref(result.data()), v2.data());
2146 mpq_canonicalize(result.data());
2149 inline std::size_t hash_value(const gmp_rational& val)
2151 std::size_t result = 0;
2152 for(int i = 0; i < std::abs(val.data()[0]._mp_num._mp_size); ++i)
2153 boost::hash_combine(result, val.data()[0]._mp_num._mp_d[i]);
2154 for(int i = 0; i < std::abs(val.data()[0]._mp_den._mp_size); ++i)
2155 boost::hash_combine(result, val.data()[0]._mp_den._mp_d[i]);
2156 boost::hash_combine(result, val.data()[0]._mp_num._mp_size);
2161 // Some member functions that are dependent upon previous code go here:
2163 template <unsigned Digits10>
2164 template <unsigned D>
2165 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= Digits10>::type*)
2167 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2168 mpf_set(this->m_data, o.data());
2170 template <unsigned Digits10>
2171 template <unsigned D>
2172 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= Digits10>::type*)
2174 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2175 mpf_set(this->m_data, o.data());
2177 template <unsigned Digits10>
2178 inline gmp_float<Digits10>::gmp_float(const gmp_int& o)
2180 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2181 mpf_set_z(this->data(), o.data());
2183 template <unsigned Digits10>
2184 inline gmp_float<Digits10>::gmp_float(const gmp_rational& o)
2186 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2187 mpf_set_q(this->data(), o.data());
2189 template <unsigned Digits10>
2190 template <unsigned D>
2191 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_float<D>& o)
2193 if(this->m_data[0]._mp_d == 0)
2194 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2195 mpf_set(this->m_data, o.data());
2198 template <unsigned Digits10>
2199 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_int& o)
2201 if(this->m_data[0]._mp_d == 0)
2202 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2203 mpf_set_z(this->data(), o.data());
2206 template <unsigned Digits10>
2207 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_rational& o)
2209 if(this->m_data[0]._mp_d == 0)
2210 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2211 mpf_set_q(this->data(), o.data());
2214 inline gmp_float<0>::gmp_float(const gmp_int& o)
2216 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
2217 mpf_set_z(this->data(), o.data());
2219 inline gmp_float<0>::gmp_float(const gmp_rational& o)
2221 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
2222 mpf_set_q(this->data(), o.data());
2224 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_int& o)
2226 if(this->m_data[0]._mp_d == 0)
2227 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision()));
2228 mpf_set_z(this->data(), o.data());
2231 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_rational& o)
2233 if(this->m_data[0]._mp_d == 0)
2234 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision()));
2235 mpf_set_q(this->data(), o.data());
2238 inline gmp_int::gmp_int(const gmp_rational& o)
2240 mpz_init(this->m_data);
2241 mpz_set_q(this->m_data, o.data());
2243 inline gmp_int& gmp_int::operator=(const gmp_rational& o)
2245 if(this->m_data[0]._mp_d == 0)
2246 mpz_init(this->m_data);
2247 mpz_set_q(this->m_data, o.data());
2251 } //namespace backends
2253 using boost::multiprecision::backends::gmp_int;
2254 using boost::multiprecision::backends::gmp_rational;
2255 using boost::multiprecision::backends::gmp_float;
2258 struct component_type<number<gmp_rational> >
2260 typedef number<gmp_int> type;
2263 template <expression_template_option ET>
2264 inline number<gmp_int, ET> numerator(const number<gmp_rational, ET>& val)
2266 number<gmp_int, ET> result;
2267 mpz_set(result.backend().data(), (mpq_numref(val.backend().data())));
2270 template <expression_template_option ET>
2271 inline number<gmp_int, ET> denominator(const number<gmp_rational, ET>& val)
2273 number<gmp_int, ET> result;
2274 mpz_set(result.backend().data(), (mpq_denref(val.backend().data())));
2280 #ifdef BOOST_NO_SFINAE_EXPR
2283 struct is_explicitly_convertible<canonical<mpf_t, gmp_int>::type, gmp_int> : public mpl::true_ {};
2285 struct is_explicitly_convertible<canonical<mpq_t, gmp_int>::type, gmp_int> : public mpl::true_ {};
2286 template<unsigned Digits10>
2287 struct is_explicitly_convertible<gmp_float<Digits10>, gmp_int> : public mpl::true_ {};
2289 struct is_explicitly_convertible<gmp_rational, gmp_int> : public mpl::true_ {};
2290 template<unsigned D1, unsigned D2>
2291 struct is_explicitly_convertible<gmp_float<D1>, gmp_float<D2> > : public mpl::true_ {};
2296 struct digits2<number<gmp_float<0>, et_on> >
2300 return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision());
2305 struct digits2<number<gmp_float<0>, et_off> >
2309 return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision());
2314 struct digits2<number<debug_adaptor<gmp_float<0> >, et_on> >
2318 return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision());
2323 struct digits2<number<debug_adaptor<gmp_float<0> >, et_off> >
2327 return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision());
2334 struct number_category<detail::canonical<mpz_t, gmp_int>::type> : public mpl::int_<number_kind_integer>{};
2336 struct number_category<detail::canonical<mpq_t, gmp_rational>::type> : public mpl::int_<number_kind_rational>{};
2338 struct number_category<detail::canonical<mpf_t, gmp_float<0> >::type> : public mpl::int_<number_kind_floating_point>{};
2341 typedef number<gmp_float<50> > mpf_float_50;
2342 typedef number<gmp_float<100> > mpf_float_100;
2343 typedef number<gmp_float<500> > mpf_float_500;
2344 typedef number<gmp_float<1000> > mpf_float_1000;
2345 typedef number<gmp_float<0> > mpf_float;
2346 typedef number<gmp_int > mpz_int;
2347 typedef number<gmp_rational > mpq_rational;
2349 } // namespace multiprecision
2351 namespace math { namespace tools{
2354 inline int digits<boost::multiprecision::mpf_float>()
2355 #ifdef BOOST_MATH_NOEXCEPT
2359 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpf_float::default_precision());
2362 inline int digits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
2363 #ifdef BOOST_MATH_NOEXCEPT
2367 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpf_float::default_precision());
2371 inline boost::multiprecision::mpf_float
2372 max_value<boost::multiprecision::mpf_float>()
2374 boost::multiprecision::mpf_float result(0.5);
2375 mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2380 inline boost::multiprecision::mpf_float
2381 min_value<boost::multiprecision::mpf_float>()
2383 boost::multiprecision::mpf_float result(0.5);
2384 mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::min)() / 64 + 1);
2389 inline boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off>
2390 max_value<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
2392 boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> result(0.5);
2393 mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2398 inline boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off>
2399 min_value<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
2401 boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> result(0.5);
2402 mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2407 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
2408 #ifdef BOOST_MATH_NOEXCEPT
2412 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >::default_precision());
2415 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
2416 #ifdef BOOST_MATH_NOEXCEPT
2420 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >::default_precision());
2424 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >
2425 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
2427 return max_value<boost::multiprecision::mpf_float>().backend();
2431 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >
2432 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
2434 return min_value<boost::multiprecision::mpf_float>().backend();
2438 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off>
2439 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
2441 return max_value<boost::multiprecision::mpf_float>().backend();
2445 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off>
2446 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
2448 return min_value<boost::multiprecision::mpf_float>().backend();
2452 }} // namespaces math::tools
2455 } // namespace boost
2460 // numeric_limits [partial] specializations for the types declared in this header:
2462 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2463 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >
2465 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> number_type;
2467 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2469 // min and max values chosen so as to not cause segfaults when calling
2470 // mpf_get_str on 64-bit Linux builds. Possibly we could use larger
2471 // exponent values elsewhere.
2473 static number_type (min)()
2475 initializer.do_nothing();
2476 static std::pair<bool, number_type> value;
2481 mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2483 return value.second;
2485 static number_type (max)()
2487 initializer.do_nothing();
2488 static std::pair<bool, number_type> value;
2493 mpf_mul_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2495 return value.second;
2497 BOOST_STATIC_CONSTEXPR number_type lowest()
2501 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301L ? 2 : 1));
2502 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
2503 // Have to allow for a possible extra limb inside the gmp data structure:
2504 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 3 + ((GMP_LIMB_BITS * 301L) / 1000L);
2505 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2506 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2507 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2508 BOOST_STATIC_CONSTEXPR int radix = 2;
2509 static number_type epsilon()
2511 initializer.do_nothing();
2512 static std::pair<bool, number_type> value;
2517 mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
2519 return value.second;
2521 // What value should this be????
2522 static number_type round_error()
2524 // returns epsilon/2
2525 initializer.do_nothing();
2526 static std::pair<bool, number_type> value;
2532 return value.second;
2534 BOOST_STATIC_CONSTEXPR long min_exponent = LONG_MIN;
2535 BOOST_STATIC_CONSTEXPR long min_exponent10 = (LONG_MIN / 1000) * 301L;
2536 BOOST_STATIC_CONSTEXPR long max_exponent = LONG_MAX;
2537 BOOST_STATIC_CONSTEXPR long max_exponent10 = (LONG_MAX / 1000) * 301L;
2538 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2539 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2540 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2541 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2542 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2543 BOOST_STATIC_CONSTEXPR number_type infinity() { return number_type(); }
2544 BOOST_STATIC_CONSTEXPR number_type quiet_NaN() { return number_type(); }
2545 BOOST_STATIC_CONSTEXPR number_type signaling_NaN() { return number_type(); }
2546 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(); }
2547 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2548 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
2549 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2550 BOOST_STATIC_CONSTEXPR bool traps = true;
2551 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2552 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate;
2555 struct data_initializer
2559 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::epsilon();
2560 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::round_error();
2561 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::min)();
2562 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::max)();
2564 void do_nothing()const{}
2566 static const data_initializer initializer;
2569 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2570 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;
2572 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2574 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2575 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits;
2576 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2577 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits10;
2578 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2579 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_digits10;
2580 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2581 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_signed;
2582 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2583 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_integer;
2584 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2585 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_exact;
2586 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2587 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::radix;
2588 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2589 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent;
2590 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2591 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent10;
2592 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2593 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent;
2594 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2595 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent10;
2596 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2597 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_infinity;
2598 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2599 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
2600 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2601 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
2602 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2603 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm;
2604 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2605 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm_loss;
2606 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2607 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_iec559;
2608 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2609 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_bounded;
2610 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2611 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_modulo;
2612 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2613 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::traps;
2614 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2615 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::tinyness_before;
2616 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2617 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::round_style;
2621 template<boost::multiprecision::expression_template_option ExpressionTemplates>
2622 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >
2624 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> number_type;
2626 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
2627 static number_type (min)() { return number_type(); }
2628 static number_type (max)() { return number_type(); }
2629 static number_type lowest() { return number_type(); }
2630 BOOST_STATIC_CONSTEXPR int digits = 0;
2631 BOOST_STATIC_CONSTEXPR int digits10 = 0;
2632 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
2633 BOOST_STATIC_CONSTEXPR bool is_signed = false;
2634 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2635 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2636 BOOST_STATIC_CONSTEXPR int radix = 0;
2637 static number_type epsilon() { return number_type(); }
2638 static number_type round_error() { return number_type(); }
2639 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
2640 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
2641 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
2642 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
2643 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2644 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2645 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2646 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2647 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2648 static number_type infinity() { return number_type(); }
2649 static number_type quiet_NaN() { return number_type(); }
2650 static number_type signaling_NaN() { return number_type(); }
2651 static number_type denorm_min() { return number_type(); }
2652 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2653 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
2654 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2655 BOOST_STATIC_CONSTEXPR bool traps = false;
2656 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2657 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate;
2660 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2662 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2663 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits;
2664 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2665 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits10;
2666 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2667 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_digits10;
2668 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2669 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_signed;
2670 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2671 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_integer;
2672 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2673 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_exact;
2674 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2675 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::radix;
2676 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2677 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent;
2678 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2679 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent10;
2680 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2681 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent;
2682 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2683 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent10;
2684 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2685 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_infinity;
2686 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2687 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_quiet_NaN;
2688 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2689 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_signaling_NaN;
2690 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2691 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm;
2692 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2693 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm_loss;
2694 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2695 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_iec559;
2696 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2697 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_bounded;
2698 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2699 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_modulo;
2700 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2701 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::traps;
2702 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2703 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::tinyness_before;
2704 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2705 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::round_style;
2709 template<boost::multiprecision::expression_template_option ExpressionTemplates>
2710 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >
2712 typedef boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> number_type;
2714 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2716 // Largest and smallest numbers are bounded only by available memory, set
2719 static number_type (min)()
2721 return number_type();
2723 static number_type (max)()
2725 return number_type();
2727 static number_type lowest() { return (min)(); }
2728 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
2729 BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
2730 BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3;
2731 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2732 BOOST_STATIC_CONSTEXPR bool is_integer = true;
2733 BOOST_STATIC_CONSTEXPR bool is_exact = true;
2734 BOOST_STATIC_CONSTEXPR int radix = 2;
2735 static number_type epsilon() { return number_type(); }
2736 static number_type round_error() { return number_type(); }
2737 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
2738 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
2739 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
2740 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
2741 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2742 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2743 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2744 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2745 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2746 static number_type infinity() { return number_type(); }
2747 static number_type quiet_NaN() { return number_type(); }
2748 static number_type signaling_NaN() { return number_type(); }
2749 static number_type denorm_min() { return number_type(); }
2750 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2751 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
2752 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2753 BOOST_STATIC_CONSTEXPR bool traps = false;
2754 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2755 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
2758 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2760 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2761 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits;
2762 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2763 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits10;
2764 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2765 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_digits10;
2766 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2767 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_signed;
2768 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2769 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_integer;
2770 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2771 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_exact;
2772 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2773 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::radix;
2774 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2775 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent;
2776 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2777 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent10;
2778 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2779 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent;
2780 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2781 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent10;
2782 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2783 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_infinity;
2784 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2785 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_quiet_NaN;
2786 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2787 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_signaling_NaN;
2788 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2789 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm;
2790 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2791 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm_loss;
2792 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2793 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_iec559;
2794 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2795 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_bounded;
2796 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2797 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_modulo;
2798 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2799 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::traps;
2800 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2801 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::tinyness_before;
2802 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2803 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::round_style;
2807 template<boost::multiprecision::expression_template_option ExpressionTemplates>
2808 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >
2810 typedef boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> number_type;
2812 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2814 // Largest and smallest numbers are bounded only by available memory, set
2817 static number_type (min)()
2819 return number_type();
2821 static number_type (max)()
2823 return number_type();
2825 static number_type lowest() { return (min)(); }
2826 // Digits are unbounded, use zero for now:
2827 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
2828 BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
2829 BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3;
2830 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2831 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2832 BOOST_STATIC_CONSTEXPR bool is_exact = true;
2833 BOOST_STATIC_CONSTEXPR int radix = 2;
2834 static number_type epsilon() { return number_type(); }
2835 static number_type round_error() { return number_type(); }
2836 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
2837 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
2838 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
2839 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
2840 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2841 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2842 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2843 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2844 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2845 static number_type infinity() { return number_type(); }
2846 static number_type quiet_NaN() { return number_type(); }
2847 static number_type signaling_NaN() { return number_type(); }
2848 static number_type denorm_min() { return number_type(); }
2849 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2850 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
2851 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2852 BOOST_STATIC_CONSTEXPR bool traps = false;
2853 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2854 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
2857 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2859 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2860 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits;
2861 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2862 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits10;
2863 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2864 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_digits10;
2865 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2866 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_signed;
2867 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2868 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_integer;
2869 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2870 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_exact;
2871 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2872 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::radix;
2873 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2874 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent;
2875 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2876 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent10;
2877 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2878 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent;
2879 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2880 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent10;
2881 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2882 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_infinity;
2883 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2884 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_quiet_NaN;
2885 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2886 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_signaling_NaN;
2887 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2888 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm;
2889 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2890 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm_loss;
2891 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2892 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_iec559;
2893 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2894 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_bounded;
2895 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2896 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_modulo;
2897 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2898 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::traps;
2899 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2900 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::tinyness_before;
2901 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2902 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::round_style;
2907 #pragma warning(pop)