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>
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
48 namespace multiprecision {
52 // warning C4127: conditional expression is constant
54 #pragma warning(disable : 4127)
57 template <unsigned digits10>
62 } // namespace backends
65 struct number_category<backends::gmp_int> : public mpl::int_<number_kind_integer>
68 struct number_category<backends::gmp_rational> : public mpl::int_<number_kind_rational>
70 template <unsigned digits10>
71 struct number_category<backends::gmp_float<digits10> > : public mpl::int_<number_kind_floating_point>
76 // Within this file, the only functions we mark as noexcept are those that manipulate
77 // (but don't create) an mpf_t. All other types may allocate at pretty much any time
78 // via a user-supplied allocator, and therefore throw.
82 template <unsigned digits10>
85 #ifdef BOOST_HAS_LONG_LONG
86 typedef mpl::list<long, boost::long_long_type> signed_types;
87 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
89 typedef mpl::list<long> signed_types;
90 typedef mpl::list<unsigned long> unsigned_types;
92 typedef mpl::list<double, long double> float_types;
93 typedef long exponent_type;
95 gmp_float_imp() BOOST_NOEXCEPT
97 m_data[0]._mp_d = 0; // uninitialized m_data
100 gmp_float_imp(const gmp_float_imp& o)
103 // We have to do an init followed by a set here, otherwise *this may be at
104 // a lower precision than o: seems like mpf_init_set copies just enough bits
105 // to get the right value, but if it's then used in further calculations
106 // things go badly wrong!!
108 mpf_init2(m_data, mpf_get_prec(o.data()));
109 if (o.m_data[0]._mp_d)
110 mpf_set(m_data, o.m_data);
112 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
113 gmp_float_imp(gmp_float_imp&& o) BOOST_NOEXCEPT
115 m_data[0] = o.m_data[0];
116 o.m_data[0]._mp_d = 0;
119 gmp_float_imp& operator=(const gmp_float_imp& o)
121 if (m_data[0]._mp_d == 0)
122 mpf_init2(m_data, mpf_get_prec(o.data()));
123 if (mpf_get_prec(data()) != mpf_get_prec(o.data()))
126 mpf_init2(t, mpf_get_prec(o.data()));
127 mpf_set(t, o.data());
133 if (o.m_data[0]._mp_d)
134 mpf_set(m_data, o.m_data);
138 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
139 gmp_float_imp& operator=(gmp_float_imp&& o) BOOST_NOEXCEPT
141 mpf_swap(m_data, o.m_data);
146 #ifdef BOOST_HAS_LONG_LONG
147 #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
148 gmp_float_imp& operator=(boost::ulong_long_type i)
150 *this = static_cast<unsigned long>(i);
154 gmp_float_imp& operator=(boost::ulong_long_type i)
156 if (m_data[0]._mp_d == 0)
157 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
158 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
161 mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
162 mpf_set_ui(m_data, 0);
165 mpf_set_ui(t, static_cast<unsigned long>(i & mask));
167 mpf_mul_2exp(t, t, shift);
168 mpf_add(m_data, m_data, t);
169 shift += std::numeric_limits<unsigned long>::digits;
170 i >>= std::numeric_limits<unsigned long>::digits;
176 gmp_float_imp& operator=(boost::long_long_type i)
178 if (m_data[0]._mp_d == 0)
179 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
181 *this = static_cast<boost::ulong_long_type>(boost::multiprecision::detail::unsigned_abs(i));
183 mpf_neg(m_data, m_data);
187 gmp_float_imp& operator=(unsigned long i)
189 if (m_data[0]._mp_d == 0)
190 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
191 mpf_set_ui(m_data, i);
194 gmp_float_imp& operator=(long i)
196 if (m_data[0]._mp_d == 0)
197 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
198 mpf_set_si(m_data, i);
201 gmp_float_imp& operator=(double d)
203 if (m_data[0]._mp_d == 0)
204 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
205 mpf_set_d(m_data, d);
208 gmp_float_imp& operator=(long double a)
214 if (m_data[0]._mp_d == 0)
215 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
219 mpf_set_si(m_data, 0);
225 mpf_set_si(m_data, 1);
229 BOOST_ASSERT(!(boost::math::isinf)(a));
230 BOOST_ASSERT(!(boost::math::isnan)(a));
234 mpf_set_ui(m_data, 0u);
238 static const int shift = std::numeric_limits<int>::digits - 1;
242 // extract int sized bits from f:
246 mpf_mul_2exp(m_data, m_data, shift);
248 mpf_add_ui(m_data, m_data, static_cast<unsigned>(term));
250 mpf_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
254 mpf_mul_2exp(m_data, m_data, e);
256 mpf_div_2exp(m_data, m_data, -e);
259 gmp_float_imp& operator=(const char* s)
261 if (m_data[0]._mp_d == 0)
262 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
263 if (0 != mpf_set_str(m_data, s, 10))
264 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid floating point number.")));
267 void swap(gmp_float_imp& o) BOOST_NOEXCEPT
269 mpf_swap(m_data, o.m_data);
271 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
273 BOOST_ASSERT(m_data[0]._mp_d);
275 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
276 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
277 std::streamsize org_digits(digits);
279 if (scientific && digits)
284 void* (*alloc_func_ptr)(size_t);
285 void* (*realloc_func_ptr)(void*, size_t, size_t);
286 void (*free_func_ptr)(void*, size_t);
287 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
289 if (mpf_sgn(m_data) == 0)
298 char* ps = mpf_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data);
299 --e; // To match with what our formatter expects.
300 if (fixed && e != -1)
302 // Oops we actually need a different number of digits to what we asked for:
303 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
307 // We need to get *all* the digits and then possibly round up,
308 // we end up with either "0" or "1" as the result.
309 ps = mpf_get_str(0, &e, 10, 0, m_data);
311 unsigned offset = *ps == '-' ? 1 : 0;
312 if (ps[offset] > '5')
318 else if (ps[offset] == '5')
320 unsigned i = offset + 1;
321 bool round_up = false;
352 ps = mpf_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data);
353 --e; // To match with what our formatter expects.
356 // in some cases, when we ask for more digits of precision, it will
357 // change the number of digits to the left of the decimal, if that
358 // happens, account for it here.
359 // example: cout << fixed << setprecision(3) << mpf_float_50("99.9809")
361 ps = mpf_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data);
362 --e; // To match with what our formatter expects.
367 ps = mpf_get_str(0, &e, 10, 1, m_data);
369 unsigned offset = *ps == '-' ? 1 : 0;
375 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
377 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, mpf_sgn(m_data) == 0);
380 ~gmp_float_imp() BOOST_NOEXCEPT
385 void negate() BOOST_NOEXCEPT
387 BOOST_ASSERT(m_data[0]._mp_d);
388 mpf_neg(m_data, m_data);
390 int compare(const gmp_float<digits10>& o) const BOOST_NOEXCEPT
392 BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
393 return mpf_cmp(m_data, o.m_data);
395 int compare(long i) const BOOST_NOEXCEPT
397 BOOST_ASSERT(m_data[0]._mp_d);
398 return mpf_cmp_si(m_data, i);
400 int compare(unsigned long i) const BOOST_NOEXCEPT
402 BOOST_ASSERT(m_data[0]._mp_d);
403 return mpf_cmp_ui(m_data, i);
406 typename enable_if<is_arithmetic<V>, int>::type compare(V v) const
408 gmp_float<digits10> d;
412 mpf_t& data() BOOST_NOEXCEPT
414 BOOST_ASSERT(m_data[0]._mp_d);
417 const mpf_t& data() const BOOST_NOEXCEPT
419 BOOST_ASSERT(m_data[0]._mp_d);
425 static unsigned& get_default_precision() BOOST_NOEXCEPT
427 static unsigned val = 50;
432 } // namespace detail
437 template <unsigned digits10>
438 struct gmp_float : public detail::gmp_float_imp<digits10>
442 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
444 gmp_float(const gmp_float& o) : detail::gmp_float_imp<digits10>(o) {}
445 template <unsigned D>
446 gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= digits10>::type* = 0);
447 template <unsigned D>
448 explicit gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= digits10>::type* = 0);
449 gmp_float(const gmp_int& o);
450 gmp_float(const gmp_rational& o);
451 gmp_float(const mpf_t val)
453 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
454 mpf_set(this->m_data, val);
456 gmp_float(const mpz_t val)
458 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
459 mpf_set_z(this->m_data, val);
461 gmp_float(const mpq_t val)
463 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
464 mpf_set_q(this->m_data, val);
466 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
467 gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<digits10>(static_cast<detail::gmp_float_imp<digits10>&&>(o))
470 gmp_float& operator=(const gmp_float& o)
472 *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10> const&>(o);
475 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
476 gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT
478 *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10>&&>(o);
482 template <unsigned D>
483 gmp_float& operator=(const gmp_float<D>& o);
484 gmp_float& operator=(const gmp_int& o);
485 gmp_float& operator=(const gmp_rational& o);
486 gmp_float& operator=(const mpf_t val)
488 if (this->m_data[0]._mp_d == 0)
489 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
490 mpf_set(this->m_data, val);
493 gmp_float& operator=(const mpz_t val)
495 if (this->m_data[0]._mp_d == 0)
496 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
497 mpf_set_z(this->m_data, val);
500 gmp_float& operator=(const mpq_t val)
502 if (this->m_data[0]._mp_d == 0)
503 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
504 mpf_set_q(this->m_data, val);
508 gmp_float& operator=(const V& v)
510 *static_cast<detail::gmp_float_imp<digits10>*>(this) = v;
516 struct gmp_float<0> : public detail::gmp_float_imp<0>
520 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
522 gmp_float(const mpf_t val)
524 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
525 mpf_set(this->m_data, val);
527 gmp_float(const mpz_t val)
529 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
530 mpf_set_z(this->m_data, val);
532 gmp_float(const mpq_t val)
534 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
535 mpf_set_q(this->m_data, val);
537 gmp_float(const gmp_float& o) : detail::gmp_float_imp<0>(o) {}
538 template <unsigned D>
539 gmp_float(const gmp_float<D>& o)
541 mpf_init2(this->m_data, mpf_get_prec(o.data()));
542 mpf_set(this->m_data, o.data());
544 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
545 gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<0>(static_cast<detail::gmp_float_imp<0>&&>(o))
548 gmp_float(const gmp_int& o);
549 gmp_float(const gmp_rational& o);
550 gmp_float(const gmp_float& o, unsigned digits10)
552 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
553 mpf_set(this->m_data, o.data());
556 gmp_float(const V& o, unsigned digits10)
558 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
562 #ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
564 // Support for new types in C++17
566 template <class Traits>
567 gmp_float(const std::basic_string_view<char, Traits>& o, unsigned digits10)
569 using default_ops::assign_from_string_view;
570 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
571 assign_from_string_view(*this, o);
574 gmp_float& operator=(const gmp_float& o)
576 *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> const&>(o);
579 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
580 gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT
582 *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0>&&>(o);
586 template <unsigned D>
587 gmp_float& operator=(const gmp_float<D>& o)
589 if (this->m_data[0]._mp_d == 0)
591 mpf_init2(this->m_data, mpf_get_prec(o.data()));
595 mpf_set_prec(this->m_data, mpf_get_prec(o.data()));
597 mpf_set(this->m_data, o.data());
600 gmp_float& operator=(const gmp_int& o);
601 gmp_float& operator=(const gmp_rational& o);
602 gmp_float& operator=(const mpf_t val)
604 if (this->m_data[0]._mp_d == 0)
605 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
606 mpf_set(this->m_data, val);
609 gmp_float& operator=(const mpz_t val)
611 if (this->m_data[0]._mp_d == 0)
612 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
613 mpf_set_z(this->m_data, val);
616 gmp_float& operator=(const mpq_t val)
618 if (this->m_data[0]._mp_d == 0)
619 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
620 mpf_set_q(this->m_data, val);
624 gmp_float& operator=(const V& v)
626 *static_cast<detail::gmp_float_imp<0>*>(this) = v;
629 static unsigned default_precision() BOOST_NOEXCEPT
631 return get_default_precision();
633 static void default_precision(unsigned v) BOOST_NOEXCEPT
635 get_default_precision() = v;
637 unsigned precision() const BOOST_NOEXCEPT
639 return static_cast<unsigned>(multiprecision::detail::digits2_2_10(static_cast<unsigned long>(mpf_get_prec(this->m_data))));
641 void precision(unsigned digits10) BOOST_NOEXCEPT
643 mpf_set_prec(this->m_data, multiprecision::detail::digits10_2_2(digits10));
647 template <unsigned digits10, class T>
648 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_eq(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
650 return a.compare(b) == 0;
652 template <unsigned digits10, class T>
653 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_lt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
655 return a.compare(b) < 0;
657 template <unsigned digits10, class T>
658 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_gt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
660 return a.compare(b) > 0;
663 template <unsigned D1, unsigned D2>
664 inline void eval_add(gmp_float<D1>& result, const gmp_float<D2>& o)
666 mpf_add(result.data(), result.data(), o.data());
668 template <unsigned D1, unsigned D2>
669 inline void eval_subtract(gmp_float<D1>& result, const gmp_float<D2>& o)
671 mpf_sub(result.data(), result.data(), o.data());
673 template <unsigned D1, unsigned D2>
674 inline void eval_multiply(gmp_float<D1>& result, const gmp_float<D2>& o)
676 mpf_mul(result.data(), result.data(), o.data());
678 template <unsigned digits10>
679 inline bool eval_is_zero(const gmp_float<digits10>& val) BOOST_NOEXCEPT
681 return mpf_sgn(val.data()) == 0;
683 template <unsigned D1, unsigned D2>
684 inline void eval_divide(gmp_float<D1>& result, const gmp_float<D2>& o)
687 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
688 mpf_div(result.data(), result.data(), o.data());
690 template <unsigned digits10>
691 inline void eval_add(gmp_float<digits10>& result, unsigned long i)
693 mpf_add_ui(result.data(), result.data(), i);
695 template <unsigned digits10>
696 inline void eval_subtract(gmp_float<digits10>& result, unsigned long i)
698 mpf_sub_ui(result.data(), result.data(), i);
700 template <unsigned digits10>
701 inline void eval_multiply(gmp_float<digits10>& result, unsigned long i)
703 mpf_mul_ui(result.data(), result.data(), i);
705 template <unsigned digits10>
706 inline void eval_divide(gmp_float<digits10>& result, unsigned long i)
709 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
710 mpf_div_ui(result.data(), result.data(), i);
712 template <unsigned digits10>
713 inline void eval_add(gmp_float<digits10>& result, long i)
716 mpf_add_ui(result.data(), result.data(), i);
718 mpf_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
720 template <unsigned digits10>
721 inline void eval_subtract(gmp_float<digits10>& result, long i)
724 mpf_sub_ui(result.data(), result.data(), i);
726 mpf_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
728 template <unsigned digits10>
729 inline void eval_multiply(gmp_float<digits10>& result, long i)
731 mpf_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
733 mpf_neg(result.data(), result.data());
735 template <unsigned digits10>
736 inline void eval_divide(gmp_float<digits10>& result, long i)
739 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
740 mpf_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
742 mpf_neg(result.data(), result.data());
745 // Specialised 3 arg versions of the basic operators:
747 template <unsigned D1, unsigned D2, unsigned D3>
748 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
750 mpf_add(a.data(), x.data(), y.data());
752 template <unsigned D1, unsigned D2>
753 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
755 mpf_add_ui(a.data(), x.data(), y);
757 template <unsigned D1, unsigned D2>
758 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
761 mpf_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
763 mpf_add_ui(a.data(), x.data(), y);
765 template <unsigned D1, unsigned D2>
766 inline void eval_add(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
768 mpf_add_ui(a.data(), y.data(), x);
770 template <unsigned D1, unsigned D2>
771 inline void eval_add(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
775 mpf_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
776 mpf_neg(a.data(), a.data());
779 mpf_add_ui(a.data(), y.data(), x);
781 template <unsigned D1, unsigned D2, unsigned D3>
782 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
784 mpf_sub(a.data(), x.data(), y.data());
786 template <unsigned D1, unsigned D2>
787 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
789 mpf_sub_ui(a.data(), x.data(), y);
791 template <unsigned D1, unsigned D2>
792 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
795 mpf_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
797 mpf_sub_ui(a.data(), x.data(), y);
799 template <unsigned D1, unsigned D2>
800 inline void eval_subtract(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
802 mpf_ui_sub(a.data(), x, y.data());
804 template <unsigned D1, unsigned D2>
805 inline void eval_subtract(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
809 mpf_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
810 mpf_neg(a.data(), a.data());
813 mpf_ui_sub(a.data(), x, y.data());
816 template <unsigned D1, unsigned D2, unsigned D3>
817 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
819 mpf_mul(a.data(), x.data(), y.data());
821 template <unsigned D1, unsigned D2>
822 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
824 mpf_mul_ui(a.data(), x.data(), y);
826 template <unsigned D1, unsigned D2>
827 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
831 mpf_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
835 mpf_mul_ui(a.data(), x.data(), y);
837 template <unsigned D1, unsigned D2>
838 inline void eval_multiply(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
840 mpf_mul_ui(a.data(), y.data(), x);
842 template <unsigned D1, unsigned D2>
843 inline void eval_multiply(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
847 mpf_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
848 mpf_neg(a.data(), a.data());
851 mpf_mul_ui(a.data(), y.data(), x);
854 template <unsigned D1, unsigned D2, unsigned D3>
855 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
858 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
859 mpf_div(a.data(), x.data(), y.data());
861 template <unsigned D1, unsigned D2>
862 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
865 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
866 mpf_div_ui(a.data(), x.data(), y);
868 template <unsigned D1, unsigned D2>
869 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
872 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
875 mpf_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
879 mpf_div_ui(a.data(), x.data(), y);
881 template <unsigned D1, unsigned D2>
882 inline void eval_divide(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
885 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
886 mpf_ui_div(a.data(), x, y.data());
888 template <unsigned D1, unsigned D2>
889 inline void eval_divide(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
892 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
895 mpf_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
896 mpf_neg(a.data(), a.data());
899 mpf_ui_div(a.data(), x, y.data());
902 template <unsigned digits10>
903 inline int eval_get_sign(const gmp_float<digits10>& val) BOOST_NOEXCEPT
905 return mpf_sgn(val.data());
908 template <unsigned digits10>
909 inline void eval_convert_to(unsigned long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
911 if (0 == mpf_fits_ulong_p(val.data()))
912 *result = (std::numeric_limits<unsigned long>::max)();
914 *result = (unsigned long)mpf_get_ui(val.data());
916 template <unsigned digits10>
917 inline void eval_convert_to(long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
919 if (0 == mpf_fits_slong_p(val.data()))
921 *result = (std::numeric_limits<long>::max)();
922 *result *= mpf_sgn(val.data());
925 *result = (long)mpf_get_si(val.data());
927 template <unsigned digits10>
928 inline void eval_convert_to(double* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
930 *result = mpf_get_d(val.data());
932 #ifdef BOOST_HAS_LONG_LONG
933 template <unsigned digits10>
934 inline void eval_convert_to(boost::long_long_type* result, const gmp_float<digits10>& val)
936 gmp_float<digits10> t(val);
937 if (eval_get_sign(t) < 0)
940 long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits;
943 mpf_div_2exp(t.data(), t.data(), digits);
945 if (!mpf_fits_slong_p(t.data()))
947 if (eval_get_sign(val) < 0)
948 *result = (std::numeric_limits<boost::long_long_type>::min)();
950 *result = (std::numeric_limits<boost::long_long_type>::max)();
954 *result = mpf_get_si(t.data());
958 digits -= std::numeric_limits<unsigned long>::digits;
959 mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
960 unsigned long l = (unsigned long)mpf_get_ui(t.data());
965 if (eval_get_sign(val) < 0)
968 template <unsigned digits10>
969 inline void eval_convert_to(boost::ulong_long_type* result, const gmp_float<digits10>& val)
971 gmp_float<digits10> t(val);
973 long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits;
976 mpf_div_2exp(t.data(), t.data(), digits);
978 if (!mpf_fits_ulong_p(t.data()))
980 *result = (std::numeric_limits<boost::long_long_type>::max)();
984 *result = mpf_get_ui(t.data());
988 digits -= std::numeric_limits<unsigned long>::digits;
989 mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
990 unsigned long l = (unsigned long)mpf_get_ui(t.data());
999 // Native non-member operations:
1001 template <unsigned Digits10>
1002 inline void eval_sqrt(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
1004 mpf_sqrt(result.data(), val.data());
1007 template <unsigned Digits10>
1008 inline void eval_abs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
1010 mpf_abs(result.data(), val.data());
1013 template <unsigned Digits10>
1014 inline void eval_fabs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
1016 mpf_abs(result.data(), val.data());
1018 template <unsigned Digits10>
1019 inline void eval_ceil(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
1021 mpf_ceil(result.data(), val.data());
1023 template <unsigned Digits10>
1024 inline void eval_floor(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
1026 mpf_floor(result.data(), val.data());
1028 template <unsigned Digits10>
1029 inline void eval_trunc(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
1031 mpf_trunc(result.data(), val.data());
1033 template <unsigned Digits10>
1034 inline void eval_ldexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long e)
1037 mpf_mul_2exp(result.data(), val.data(), e);
1039 mpf_div_2exp(result.data(), val.data(), -e);
1043 template <unsigned Digits10>
1044 inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, int* e)
1046 #if (BOOST_MP_MPIR_VERSION >= 20600) && (BOOST_MP_MPIR_VERSION < 30000)
1048 mpf_get_d_2exp(&v, val.data());
1051 mpf_get_d_2exp(&v, val.data());
1054 eval_ldexp(result, val, -v);
1056 template <unsigned Digits10>
1057 inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long* e)
1059 #if (BOOST_MP_MPIR_VERSION >= 20600) && (BOOST_MP_MPIR_VERSION < 30000)
1061 mpf_get_d_2exp(&v, val.data());
1063 eval_ldexp(result, val, -v);
1065 mpf_get_d_2exp(e, val.data());
1066 eval_ldexp(result, val, -*e);
1070 template <unsigned Digits10>
1071 inline std::size_t hash_value(const gmp_float<Digits10>& val)
1073 std::size_t result = 0;
1074 for (int i = 0; i < std::abs(val.data()[0]._mp_size); ++i)
1075 boost::hash_combine(result, val.data()[0]._mp_d[i]);
1076 boost::hash_combine(result, val.data()[0]._mp_exp);
1077 boost::hash_combine(result, val.data()[0]._mp_size);
1083 #ifdef BOOST_HAS_LONG_LONG
1084 typedef mpl::list<long, boost::long_long_type> signed_types;
1085 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
1087 typedef mpl::list<long> signed_types;
1088 typedef mpl::list<unsigned long> unsigned_types;
1090 typedef mpl::list<double, long double> float_types;
1094 mpz_init(this->m_data);
1096 gmp_int(const gmp_int& o)
1098 if (o.m_data[0]._mp_d)
1099 mpz_init_set(m_data, o.m_data);
1101 mpz_init(this->m_data);
1103 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1104 gmp_int(gmp_int&& o) BOOST_NOEXCEPT
1106 m_data[0] = o.m_data[0];
1107 o.m_data[0]._mp_d = 0;
1110 explicit gmp_int(const mpf_t val)
1112 mpz_init(this->m_data);
1113 mpz_set_f(this->m_data, val);
1115 gmp_int(const mpz_t val)
1117 mpz_init_set(this->m_data, val);
1119 explicit gmp_int(const mpq_t val)
1121 mpz_init(this->m_data);
1122 mpz_set_q(this->m_data, val);
1124 template <unsigned Digits10>
1125 explicit gmp_int(const gmp_float<Digits10>& o)
1127 mpz_init(this->m_data);
1128 mpz_set_f(this->m_data, o.data());
1130 explicit gmp_int(const gmp_rational& o);
1131 gmp_int& operator=(const gmp_int& o)
1133 if (m_data[0]._mp_d == 0)
1134 mpz_init(this->m_data);
1135 mpz_set(m_data, o.m_data);
1138 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1139 gmp_int& operator=(gmp_int&& o) BOOST_NOEXCEPT
1141 mpz_swap(m_data, o.m_data);
1145 #ifdef BOOST_HAS_LONG_LONG
1146 #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
1147 gmp_int& operator=(boost::ulong_long_type i)
1149 *this = static_cast<unsigned long>(i);
1153 gmp_int& operator=(boost::ulong_long_type i)
1155 if (m_data[0]._mp_d == 0)
1156 mpz_init(this->m_data);
1157 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
1160 mpz_set_ui(m_data, 0);
1161 mpz_init_set_ui(t, 0);
1164 mpz_set_ui(t, static_cast<unsigned long>(i & mask));
1166 mpz_mul_2exp(t, t, shift);
1167 mpz_add(m_data, m_data, t);
1168 shift += std::numeric_limits<unsigned long>::digits;
1169 i >>= std::numeric_limits<unsigned long>::digits;
1175 gmp_int& operator=(boost::long_long_type i)
1177 if (m_data[0]._mp_d == 0)
1178 mpz_init(this->m_data);
1180 *this = boost::multiprecision::detail::unsigned_abs(i);
1182 mpz_neg(m_data, m_data);
1186 gmp_int& operator=(unsigned long i)
1188 if (m_data[0]._mp_d == 0)
1189 mpz_init(this->m_data);
1190 mpz_set_ui(m_data, i);
1193 gmp_int& operator=(long i)
1195 if (m_data[0]._mp_d == 0)
1196 mpz_init(this->m_data);
1197 mpz_set_si(m_data, i);
1200 gmp_int& operator=(double d)
1202 if (m_data[0]._mp_d == 0)
1203 mpz_init(this->m_data);
1204 mpz_set_d(m_data, d);
1207 gmp_int& operator=(long double a)
1213 if (m_data[0]._mp_d == 0)
1214 mpz_init(this->m_data);
1218 mpz_set_si(m_data, 0);
1224 mpz_set_si(m_data, 1);
1228 BOOST_ASSERT(!(boost::math::isinf)(a));
1229 BOOST_ASSERT(!(boost::math::isnan)(a));
1232 long double f, term;
1233 mpz_set_ui(m_data, 0u);
1237 static const int shift = std::numeric_limits<int>::digits - 1;
1241 // extract int sized bits from f:
1242 f = ldexp(f, shift);
1245 mpz_mul_2exp(m_data, m_data, shift);
1247 mpz_add_ui(m_data, m_data, static_cast<unsigned>(term));
1249 mpz_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
1253 mpz_mul_2exp(m_data, m_data, e);
1255 mpz_div_2exp(m_data, m_data, -e);
1258 gmp_int& operator=(const char* s)
1260 if (m_data[0]._mp_d == 0)
1261 mpz_init(this->m_data);
1262 std::size_t n = s ? std::strlen(s) : 0;
1264 if (n && (*s == '0'))
1266 if ((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
1280 if (0 != mpz_set_str(m_data, s, radix))
1281 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid integer.")));
1284 mpz_set_ui(m_data, 0);
1287 gmp_int& operator=(const mpf_t val)
1289 if (m_data[0]._mp_d == 0)
1290 mpz_init(this->m_data);
1291 mpz_set_f(this->m_data, val);
1294 gmp_int& operator=(const mpz_t val)
1296 if (m_data[0]._mp_d == 0)
1297 mpz_init(this->m_data);
1298 mpz_set(this->m_data, val);
1301 gmp_int& operator=(const mpq_t val)
1303 if (m_data[0]._mp_d == 0)
1304 mpz_init(this->m_data);
1305 mpz_set_q(this->m_data, val);
1308 template <unsigned Digits10>
1309 gmp_int& operator=(const gmp_float<Digits10>& o)
1311 if (m_data[0]._mp_d == 0)
1312 mpz_init(this->m_data);
1313 mpz_set_f(this->m_data, o.data());
1316 gmp_int& operator=(const gmp_rational& o);
1317 void swap(gmp_int& o)
1319 mpz_swap(m_data, o.m_data);
1321 std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f) const
1323 BOOST_ASSERT(m_data[0]._mp_d);
1326 if ((f & std::ios_base::oct) == std::ios_base::oct)
1328 else if ((f & std::ios_base::hex) == std::ios_base::hex)
1331 // sanity check, bases 8 and 16 are only available for positive numbers:
1333 if ((base != 10) && (mpz_sgn(m_data) < 0))
1334 BOOST_THROW_EXCEPTION(std::runtime_error("Formatted output in bases 8 or 16 is only available for positive numbers"));
1335 void* (*alloc_func_ptr)(size_t);
1336 void* (*realloc_func_ptr)(void*, size_t, size_t);
1337 void (*free_func_ptr)(void*, size_t);
1338 const char* ps = mpz_get_str(0, base, m_data);
1340 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
1341 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
1342 if (f & std::ios_base::uppercase)
1343 for (size_t i = 0; i < s.length(); ++i)
1344 s[i] = std::toupper(s[i]);
1345 if ((base != 10) && (f & std::ios_base::showbase))
1347 int pos = s[0] == '-' ? 1 : 0;
1348 const char* pp = base == 8 ? "0" : (f & std::ios_base::uppercase) ? "0X" : "0x";
1349 s.insert(static_cast<std::string::size_type>(pos), pp);
1351 if ((f & std::ios_base::showpos) && (s[0] != '-'))
1352 s.insert(static_cast<std::string::size_type>(0), 1, '+');
1356 ~gmp_int() BOOST_NOEXCEPT
1358 if (m_data[0]._mp_d)
1361 void negate() BOOST_NOEXCEPT
1363 BOOST_ASSERT(m_data[0]._mp_d);
1364 mpz_neg(m_data, m_data);
1366 int compare(const gmp_int& o) const BOOST_NOEXCEPT
1368 BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
1369 return mpz_cmp(m_data, o.m_data);
1371 int compare(long i) const BOOST_NOEXCEPT
1373 BOOST_ASSERT(m_data[0]._mp_d);
1374 return mpz_cmp_si(m_data, i);
1376 int compare(unsigned long i) const BOOST_NOEXCEPT
1378 BOOST_ASSERT(m_data[0]._mp_d);
1379 return mpz_cmp_ui(m_data, i);
1382 int compare(V v) const
1388 mpz_t& data() BOOST_NOEXCEPT
1390 BOOST_ASSERT(m_data[0]._mp_d);
1393 const mpz_t& data() const BOOST_NOEXCEPT
1395 BOOST_ASSERT(m_data[0]._mp_d);
1404 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const gmp_int& a, const T& b)
1406 return a.compare(b) == 0;
1409 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const gmp_int& a, const T& b)
1411 return a.compare(b) < 0;
1414 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const gmp_int& a, const T& b)
1416 return a.compare(b) > 0;
1419 inline bool eval_is_zero(const gmp_int& val)
1421 return mpz_sgn(val.data()) == 0;
1423 inline void eval_add(gmp_int& t, const gmp_int& o)
1425 mpz_add(t.data(), t.data(), o.data());
1427 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, const gmp_int& b)
1429 mpz_addmul(t.data(), a.data(), b.data());
1431 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, const gmp_int& b)
1433 mpz_submul(t.data(), a.data(), b.data());
1435 inline void eval_subtract(gmp_int& t, const gmp_int& o)
1437 mpz_sub(t.data(), t.data(), o.data());
1439 inline void eval_multiply(gmp_int& t, const gmp_int& o)
1441 mpz_mul(t.data(), t.data(), o.data());
1443 inline void eval_divide(gmp_int& t, const gmp_int& o)
1445 if (eval_is_zero(o))
1446 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1447 mpz_tdiv_q(t.data(), t.data(), o.data());
1449 inline void eval_modulus(gmp_int& t, const gmp_int& o)
1451 mpz_tdiv_r(t.data(), t.data(), o.data());
1453 inline void eval_add(gmp_int& t, unsigned long i)
1455 mpz_add_ui(t.data(), t.data(), i);
1457 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, unsigned long i)
1459 mpz_addmul_ui(t.data(), a.data(), i);
1461 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, unsigned long i)
1463 mpz_submul_ui(t.data(), a.data(), i);
1465 inline void eval_subtract(gmp_int& t, unsigned long i)
1467 mpz_sub_ui(t.data(), t.data(), i);
1469 inline void eval_multiply(gmp_int& t, unsigned long i)
1471 mpz_mul_ui(t.data(), t.data(), i);
1473 inline void eval_modulus(gmp_int& t, unsigned long i)
1475 mpz_tdiv_r_ui(t.data(), t.data(), i);
1477 inline void eval_divide(gmp_int& t, unsigned long i)
1480 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1481 mpz_tdiv_q_ui(t.data(), t.data(), i);
1483 inline void eval_add(gmp_int& t, long i)
1486 mpz_add_ui(t.data(), t.data(), i);
1488 mpz_sub_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1490 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, long i)
1493 mpz_addmul_ui(t.data(), a.data(), i);
1495 mpz_submul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i));
1497 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, long i)
1500 mpz_submul_ui(t.data(), a.data(), i);
1502 mpz_addmul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i));
1504 inline void eval_subtract(gmp_int& t, long i)
1507 mpz_sub_ui(t.data(), t.data(), i);
1509 mpz_add_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1511 inline void eval_multiply(gmp_int& t, long i)
1513 mpz_mul_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1515 mpz_neg(t.data(), t.data());
1517 inline void eval_modulus(gmp_int& t, long i)
1519 mpz_tdiv_r_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1521 inline void eval_divide(gmp_int& t, long i)
1524 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1525 mpz_tdiv_q_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
1527 mpz_neg(t.data(), t.data());
1530 inline void eval_left_shift(gmp_int& t, UI i)
1532 mpz_mul_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
1535 inline void eval_right_shift(gmp_int& t, UI i)
1537 mpz_fdiv_q_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
1540 inline void eval_left_shift(gmp_int& t, const gmp_int& v, UI i)
1542 mpz_mul_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
1545 inline void eval_right_shift(gmp_int& t, const gmp_int& v, UI i)
1547 mpz_fdiv_q_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
1550 inline void eval_bitwise_and(gmp_int& result, const gmp_int& v)
1552 mpz_and(result.data(), result.data(), v.data());
1555 inline void eval_bitwise_or(gmp_int& result, const gmp_int& v)
1557 mpz_ior(result.data(), result.data(), v.data());
1560 inline void eval_bitwise_xor(gmp_int& result, const gmp_int& v)
1562 mpz_xor(result.data(), result.data(), v.data());
1565 inline void eval_add(gmp_int& t, const gmp_int& p, const gmp_int& o)
1567 mpz_add(t.data(), p.data(), o.data());
1569 inline void eval_subtract(gmp_int& t, const gmp_int& p, const gmp_int& o)
1571 mpz_sub(t.data(), p.data(), o.data());
1573 inline void eval_multiply(gmp_int& t, const gmp_int& p, const gmp_int& o)
1575 mpz_mul(t.data(), p.data(), o.data());
1577 inline void eval_divide(gmp_int& t, const gmp_int& p, const gmp_int& o)
1579 if (eval_is_zero(o))
1580 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1581 mpz_tdiv_q(t.data(), p.data(), o.data());
1583 inline void eval_modulus(gmp_int& t, const gmp_int& p, const gmp_int& o)
1585 mpz_tdiv_r(t.data(), p.data(), o.data());
1587 inline void eval_add(gmp_int& t, const gmp_int& p, unsigned long i)
1589 mpz_add_ui(t.data(), p.data(), i);
1591 inline void eval_subtract(gmp_int& t, const gmp_int& p, unsigned long i)
1593 mpz_sub_ui(t.data(), p.data(), i);
1595 inline void eval_multiply(gmp_int& t, const gmp_int& p, unsigned long i)
1597 mpz_mul_ui(t.data(), p.data(), i);
1599 inline void eval_modulus(gmp_int& t, const gmp_int& p, unsigned long i)
1601 mpz_tdiv_r_ui(t.data(), p.data(), i);
1603 inline void eval_divide(gmp_int& t, const gmp_int& p, unsigned long i)
1606 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1607 mpz_tdiv_q_ui(t.data(), p.data(), i);
1609 inline void eval_add(gmp_int& t, const gmp_int& p, long i)
1612 mpz_add_ui(t.data(), p.data(), i);
1614 mpz_sub_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1616 inline void eval_subtract(gmp_int& t, const gmp_int& p, long i)
1619 mpz_sub_ui(t.data(), p.data(), i);
1621 mpz_add_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1623 inline void eval_multiply(gmp_int& t, const gmp_int& p, long i)
1625 mpz_mul_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1627 mpz_neg(t.data(), t.data());
1629 inline void eval_modulus(gmp_int& t, const gmp_int& p, long i)
1631 mpz_tdiv_r_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1633 inline void eval_divide(gmp_int& t, const gmp_int& p, long i)
1636 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
1637 mpz_tdiv_q_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
1639 mpz_neg(t.data(), t.data());
1642 inline void eval_bitwise_and(gmp_int& result, const gmp_int& u, const gmp_int& v)
1644 mpz_and(result.data(), u.data(), v.data());
1647 inline void eval_bitwise_or(gmp_int& result, const gmp_int& u, const gmp_int& v)
1649 mpz_ior(result.data(), u.data(), v.data());
1652 inline void eval_bitwise_xor(gmp_int& result, const gmp_int& u, const gmp_int& v)
1654 mpz_xor(result.data(), u.data(), v.data());
1657 inline void eval_complement(gmp_int& result, const gmp_int& u)
1659 mpz_com(result.data(), u.data());
1662 inline int eval_get_sign(const gmp_int& val)
1664 return mpz_sgn(val.data());
1666 inline void eval_convert_to(unsigned long* result, const gmp_int& val)
1668 if (mpz_sgn(val.data()) < 0)
1670 BOOST_THROW_EXCEPTION(std::range_error("Conversion from negative integer to an unsigned type results in undefined behaviour"));
1673 *result = (unsigned long)mpz_get_ui(val.data());
1675 inline void eval_convert_to(long* result, const gmp_int& val)
1677 if (0 == mpz_fits_slong_p(val.data()))
1679 *result = mpz_sgn(val.data()) < 0 ? (std::numeric_limits<long>::min)() : (std::numeric_limits<long>::max)();
1682 *result = (signed long)mpz_get_si(val.data());
1684 inline void eval_convert_to(double* result, const gmp_int& val)
1686 *result = mpz_get_d(val.data());
1689 inline void eval_abs(gmp_int& result, const gmp_int& val)
1691 mpz_abs(result.data(), val.data());
1694 inline void eval_gcd(gmp_int& result, const gmp_int& a, const gmp_int& b)
1696 mpz_gcd(result.data(), a.data(), b.data());
1698 inline void eval_lcm(gmp_int& result, const gmp_int& a, const gmp_int& b)
1700 mpz_lcm(result.data(), a.data(), b.data());
1703 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)
1705 mpz_gcd_ui(result.data(), a.data(), b);
1708 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)
1710 mpz_lcm_ui(result.data(), a.data(), b);
1713 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)
1715 mpz_gcd_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b));
1718 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)
1720 mpz_lcm_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b));
1723 inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x)
1725 mpz_sqrtrem(s.data(), r.data(), x.data());
1728 inline unsigned eval_lsb(const gmp_int& val)
1730 int c = eval_get_sign(val);
1733 BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
1737 BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
1739 return static_cast<unsigned>(mpz_scan1(val.data(), 0));
1742 inline unsigned eval_msb(const gmp_int& val)
1744 int c = eval_get_sign(val);
1747 BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
1751 BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
1753 return static_cast<unsigned>(mpz_sizeinbase(val.data(), 2) - 1);
1756 inline bool eval_bit_test(const gmp_int& val, unsigned index)
1758 return mpz_tstbit(val.data(), index) ? true : false;
1761 inline void eval_bit_set(gmp_int& val, unsigned index)
1763 mpz_setbit(val.data(), index);
1766 inline void eval_bit_unset(gmp_int& val, unsigned index)
1768 mpz_clrbit(val.data(), index);
1771 inline void eval_bit_flip(gmp_int& val, unsigned index)
1773 mpz_combit(val.data(), index);
1776 inline void eval_qr(const gmp_int& x, const gmp_int& y,
1777 gmp_int& q, gmp_int& r)
1779 mpz_tdiv_qr(q.data(), r.data(), x.data(), y.data());
1782 template <class Integer>
1783 inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
1785 #if defined(__MPIR_VERSION) && (__MPIR_VERSION >= 3)
1786 if ((sizeof(Integer) <= sizeof(mpir_ui)) || (val <= (std::numeric_limits<mpir_ui>::max)()))
1788 if ((sizeof(Integer) <= sizeof(long)) || (val <= (std::numeric_limits<unsigned long>::max)()))
1791 return static_cast<Integer>(mpz_tdiv_ui(x.data(), val));
1795 return default_ops::eval_integer_modulus(x, val);
1798 template <class Integer>
1799 inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
1801 return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val));
1803 inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m)
1805 if (eval_get_sign(p) < 0)
1807 BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
1809 mpz_powm(result.data(), base.data(), p.data(), m.data());
1812 template <class Integer>
1813 inline typename enable_if<
1815 is_unsigned<Integer>,
1816 mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)> > >::type
1817 eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
1819 mpz_powm_ui(result.data(), base.data(), p, m.data());
1821 template <class Integer>
1822 inline typename enable_if<
1825 mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)> > >::type
1826 eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
1830 BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
1832 mpz_powm_ui(result.data(), base.data(), p, m.data());
1835 inline std::size_t hash_value(const gmp_int& val)
1837 // We should really use mpz_limbs_read here, but that's unsupported on older versions:
1838 std::size_t result = 0;
1839 for (int i = 0; i < std::abs(val.data()[0]._mp_size); ++i)
1840 boost::hash_combine(result, val.data()[0]._mp_d[i]);
1841 boost::hash_combine(result, val.data()[0]._mp_size);
1845 struct gmp_rational;
1846 void eval_add(gmp_rational& t, const gmp_rational& o);
1850 #ifdef BOOST_HAS_LONG_LONG
1851 typedef mpl::list<long, boost::long_long_type> signed_types;
1852 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
1854 typedef mpl::list<long> signed_types;
1855 typedef mpl::list<unsigned long> unsigned_types;
1857 typedef mpl::list<double, long double> float_types;
1861 mpq_init(this->m_data);
1863 gmp_rational(const gmp_rational& o)
1866 if (o.m_data[0]._mp_num._mp_d)
1867 mpq_set(m_data, o.m_data);
1869 gmp_rational(const gmp_int& o)
1872 mpq_set_z(m_data, o.data());
1874 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1875 gmp_rational(gmp_rational&& o) BOOST_NOEXCEPT
1877 m_data[0] = o.m_data[0];
1878 o.m_data[0]._mp_num._mp_d = 0;
1879 o.m_data[0]._mp_den._mp_d = 0;
1882 gmp_rational(const mpq_t o)
1887 gmp_rational(const mpz_t o)
1890 mpq_set_z(m_data, o);
1892 gmp_rational& operator=(const gmp_rational& o)
1894 if (m_data[0]._mp_den._mp_d == 0)
1896 mpq_set(m_data, o.m_data);
1899 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1900 gmp_rational& operator=(gmp_rational&& o) BOOST_NOEXCEPT
1902 mpq_swap(m_data, o.m_data);
1906 #ifdef BOOST_HAS_LONG_LONG
1907 #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
1908 gmp_rational& operator=(boost::ulong_long_type i)
1910 *this = static_cast<unsigned long>(i);
1914 gmp_rational& operator=(boost::ulong_long_type i)
1916 if (m_data[0]._mp_den._mp_d == 0)
1920 mpq_set_z(m_data, zi.data());
1923 gmp_rational& operator=(boost::long_long_type i)
1925 if (m_data[0]._mp_den._mp_d == 0)
1928 *this = boost::multiprecision::detail::unsigned_abs(i);
1930 mpq_neg(m_data, m_data);
1935 gmp_rational& operator=(unsigned long i)
1937 if (m_data[0]._mp_den._mp_d == 0)
1939 mpq_set_ui(m_data, i, 1);
1942 gmp_rational& operator=(long i)
1944 if (m_data[0]._mp_den._mp_d == 0)
1946 mpq_set_si(m_data, i, 1);
1949 gmp_rational& operator=(double d)
1951 if (m_data[0]._mp_den._mp_d == 0)
1953 mpq_set_d(m_data, d);
1956 gmp_rational& operator=(long double a)
1958 using default_ops::eval_add;
1959 using default_ops::eval_subtract;
1964 if (m_data[0]._mp_den._mp_d == 0)
1969 mpq_set_si(m_data, 0, 1);
1975 mpq_set_si(m_data, 1, 1);
1979 BOOST_ASSERT(!(boost::math::isinf)(a));
1980 BOOST_ASSERT(!(boost::math::isnan)(a));
1983 long double f, term;
1984 mpq_set_ui(m_data, 0, 1);
1985 mpq_set_ui(m_data, 0u, 1);
1990 static const int shift = std::numeric_limits<int>::digits - 1;
1994 // extract int sized bits from f:
1995 f = ldexp(f, shift);
1998 mpq_mul_2exp(m_data, m_data, shift);
1999 t = static_cast<long>(term);
2004 mpq_mul_2exp(m_data, m_data, e);
2006 mpq_div_2exp(m_data, m_data, -e);
2009 gmp_rational& operator=(const char* s)
2011 if (m_data[0]._mp_den._mp_d == 0)
2013 if (0 != mpq_set_str(m_data, s, 10))
2014 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid rational number.")));
2017 gmp_rational& operator=(const gmp_int& o)
2019 if (m_data[0]._mp_den._mp_d == 0)
2021 mpq_set_z(m_data, o.data());
2024 gmp_rational& operator=(const mpq_t o)
2026 if (m_data[0]._mp_den._mp_d == 0)
2031 gmp_rational& operator=(const mpz_t o)
2033 if (m_data[0]._mp_den._mp_d == 0)
2035 mpq_set_z(m_data, o);
2038 void swap(gmp_rational& o)
2040 mpq_swap(m_data, o.m_data);
2042 std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags /*f*/) const
2044 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2045 // TODO make a better job of this including handling of f!!
2046 void* (*alloc_func_ptr)(size_t);
2047 void* (*realloc_func_ptr)(void*, size_t, size_t);
2048 void (*free_func_ptr)(void*, size_t);
2049 const char* ps = mpq_get_str(0, 10, m_data);
2051 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
2052 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
2057 if (m_data[0]._mp_num._mp_d || m_data[0]._mp_den._mp_d)
2062 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2063 mpq_neg(m_data, m_data);
2065 int compare(const gmp_rational& o) const
2067 BOOST_ASSERT(m_data[0]._mp_num._mp_d && o.m_data[0]._mp_num._mp_d);
2068 return mpq_cmp(m_data, o.m_data);
2071 int compare(V v) const
2077 int compare(unsigned long v) const
2079 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2080 return mpq_cmp_ui(m_data, v, 1);
2082 int compare(long v) const
2084 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2085 return mpq_cmp_si(m_data, v, 1);
2089 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2092 const mpq_t& data() const
2094 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
2102 inline bool eval_is_zero(const gmp_rational& val)
2104 return mpq_sgn(val.data()) == 0;
2107 inline bool eval_eq(gmp_rational& a, const T& b)
2109 return a.compare(b) == 0;
2112 inline bool eval_lt(gmp_rational& a, const T& b)
2114 return a.compare(b) < 0;
2117 inline bool eval_gt(gmp_rational& a, const T& b)
2119 return a.compare(b) > 0;
2122 inline void eval_add(gmp_rational& t, const gmp_rational& o)
2124 mpq_add(t.data(), t.data(), o.data());
2126 inline void eval_subtract(gmp_rational& t, const gmp_rational& o)
2128 mpq_sub(t.data(), t.data(), o.data());
2130 inline void eval_multiply(gmp_rational& t, const gmp_rational& o)
2132 mpq_mul(t.data(), t.data(), o.data());
2134 inline void eval_divide(gmp_rational& t, const gmp_rational& o)
2136 if (eval_is_zero(o))
2137 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
2138 mpq_div(t.data(), t.data(), o.data());
2140 inline void eval_add(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
2142 mpq_add(t.data(), p.data(), o.data());
2144 inline void eval_subtract(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
2146 mpq_sub(t.data(), p.data(), o.data());
2148 inline void eval_multiply(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
2150 mpq_mul(t.data(), p.data(), o.data());
2152 inline void eval_divide(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
2154 if (eval_is_zero(o))
2155 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
2156 mpq_div(t.data(), p.data(), o.data());
2159 inline int eval_get_sign(const gmp_rational& val)
2161 return mpq_sgn(val.data());
2163 inline void eval_convert_to(double* result, const gmp_rational& val)
2166 // This does not round correctly:
2168 //*result = mpq_get_d(val.data());
2172 boost::multiprecision::detail::generic_convert_rational_to_float(*result, val);
2175 inline void eval_convert_to(long* result, const gmp_rational& val)
2178 eval_convert_to(&r, val);
2179 *result = static_cast<long>(r);
2182 inline void eval_convert_to(unsigned long* result, const gmp_rational& val)
2185 eval_convert_to(&r, val);
2186 *result = static_cast<long>(r);
2189 inline void eval_abs(gmp_rational& result, const gmp_rational& val)
2191 mpq_abs(result.data(), val.data());
2194 inline void assign_components(gmp_rational& result, unsigned long v1, unsigned long v2)
2196 mpq_set_ui(result.data(), v1, v2);
2197 mpq_canonicalize(result.data());
2199 inline void assign_components(gmp_rational& result, long v1, long v2)
2201 mpq_set_si(result.data(), v1, v2);
2202 mpq_canonicalize(result.data());
2204 inline void assign_components(gmp_rational& result, gmp_int const& v1, gmp_int const& v2)
2206 mpz_set(mpq_numref(result.data()), v1.data());
2207 mpz_set(mpq_denref(result.data()), v2.data());
2208 mpq_canonicalize(result.data());
2211 inline std::size_t hash_value(const gmp_rational& val)
2213 std::size_t result = 0;
2214 for (int i = 0; i < std::abs(val.data()[0]._mp_num._mp_size); ++i)
2215 boost::hash_combine(result, val.data()[0]._mp_num._mp_d[i]);
2216 for (int i = 0; i < std::abs(val.data()[0]._mp_den._mp_size); ++i)
2217 boost::hash_combine(result, val.data()[0]._mp_den._mp_d[i]);
2218 boost::hash_combine(result, val.data()[0]._mp_num._mp_size);
2223 // Some member functions that are dependent upon previous code go here:
2225 template <unsigned Digits10>
2226 template <unsigned D>
2227 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= Digits10>::type*)
2229 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2230 mpf_set(this->m_data, o.data());
2232 template <unsigned Digits10>
2233 template <unsigned D>
2234 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= Digits10>::type*)
2236 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2237 mpf_set(this->m_data, o.data());
2239 template <unsigned Digits10>
2240 inline gmp_float<Digits10>::gmp_float(const gmp_int& o)
2242 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2243 mpf_set_z(this->data(), o.data());
2245 template <unsigned Digits10>
2246 inline gmp_float<Digits10>::gmp_float(const gmp_rational& o)
2248 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2249 mpf_set_q(this->data(), o.data());
2251 template <unsigned Digits10>
2252 template <unsigned D>
2253 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_float<D>& o)
2255 if (this->m_data[0]._mp_d == 0)
2256 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2257 mpf_set(this->m_data, o.data());
2260 template <unsigned Digits10>
2261 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_int& o)
2263 if (this->m_data[0]._mp_d == 0)
2264 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2265 mpf_set_z(this->data(), o.data());
2268 template <unsigned Digits10>
2269 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_rational& o)
2271 if (this->m_data[0]._mp_d == 0)
2272 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
2273 mpf_set_q(this->data(), o.data());
2276 inline gmp_float<0>::gmp_float(const gmp_int& o)
2278 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
2279 mpf_set_z(this->data(), o.data());
2281 inline gmp_float<0>::gmp_float(const gmp_rational& o)
2283 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
2284 mpf_set_q(this->data(), o.data());
2286 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_int& o)
2288 if (this->m_data[0]._mp_d == 0)
2289 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision()));
2290 mpf_set_z(this->data(), o.data());
2293 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_rational& o)
2295 if (this->m_data[0]._mp_d == 0)
2296 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision()));
2297 mpf_set_q(this->data(), o.data());
2300 inline gmp_int::gmp_int(const gmp_rational& o)
2302 mpz_init(this->m_data);
2303 mpz_set_q(this->m_data, o.data());
2305 inline gmp_int& gmp_int::operator=(const gmp_rational& o)
2307 if (this->m_data[0]._mp_d == 0)
2308 mpz_init(this->m_data);
2309 mpz_set_q(this->m_data, o.data());
2313 } //namespace backends
2315 using boost::multiprecision::backends::gmp_float;
2316 using boost::multiprecision::backends::gmp_int;
2317 using boost::multiprecision::backends::gmp_rational;
2319 template <expression_template_option ExpressionTemplates>
2320 struct component_type<number<gmp_rational, ExpressionTemplates> >
2322 typedef number<gmp_int, ExpressionTemplates> type;
2325 template <expression_template_option ET>
2326 inline number<gmp_int, ET> numerator(const number<gmp_rational, ET>& val)
2328 number<gmp_int, ET> result;
2329 mpz_set(result.backend().data(), (mpq_numref(val.backend().data())));
2332 template <expression_template_option ET>
2333 inline number<gmp_int, ET> denominator(const number<gmp_rational, ET>& val)
2335 number<gmp_int, ET> result;
2336 mpz_set(result.backend().data(), (mpq_denref(val.backend().data())));
2342 #ifdef BOOST_NO_SFINAE_EXPR
2345 struct is_explicitly_convertible<canonical<mpf_t, gmp_int>::type, gmp_int> : public mpl::true_
2348 struct is_explicitly_convertible<canonical<mpq_t, gmp_int>::type, gmp_int> : public mpl::true_
2350 template <unsigned Digits10>
2351 struct is_explicitly_convertible<gmp_float<Digits10>, gmp_int> : public mpl::true_
2354 struct is_explicitly_convertible<gmp_rational, gmp_int> : public mpl::true_
2356 template <unsigned D1, unsigned D2>
2357 struct is_explicitly_convertible<gmp_float<D1>, gmp_float<D2> > : public mpl::true_
2363 struct digits2<number<gmp_float<0>, et_on> >
2367 return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision());
2372 struct digits2<number<gmp_float<0>, et_off> >
2376 return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision());
2381 struct digits2<number<debug_adaptor<gmp_float<0> >, et_on> >
2385 return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision());
2390 struct digits2<number<debug_adaptor<gmp_float<0> >, et_off> >
2394 return multiprecision::detail::digits10_2_2(gmp_float<0>::default_precision());
2398 } // namespace detail
2401 struct number_category<detail::canonical<mpz_t, gmp_int>::type> : public mpl::int_<number_kind_integer>
2404 struct number_category<detail::canonical<mpq_t, gmp_rational>::type> : public mpl::int_<number_kind_rational>
2407 struct number_category<detail::canonical<mpf_t, gmp_float<0> >::type> : public mpl::int_<number_kind_floating_point>
2412 struct is_variable_precision<backends::gmp_float<0> > : public true_type
2414 } // namespace detail
2416 typedef number<gmp_float<50> > mpf_float_50;
2417 typedef number<gmp_float<100> > mpf_float_100;
2418 typedef number<gmp_float<500> > mpf_float_500;
2419 typedef number<gmp_float<1000> > mpf_float_1000;
2420 typedef number<gmp_float<0> > mpf_float;
2421 typedef number<gmp_int> mpz_int;
2422 typedef number<gmp_rational> mpq_rational;
2424 } // namespace multiprecision
2426 namespace math { namespace tools {
2429 inline int digits<boost::multiprecision::mpf_float>()
2430 #ifdef BOOST_MATH_NOEXCEPT
2434 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpf_float::default_precision());
2437 inline int digits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
2438 #ifdef BOOST_MATH_NOEXCEPT
2442 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpf_float::default_precision());
2446 inline boost::multiprecision::mpf_float
2447 max_value<boost::multiprecision::mpf_float>()
2449 boost::multiprecision::mpf_float result(0.5);
2450 mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2455 inline boost::multiprecision::mpf_float
2456 min_value<boost::multiprecision::mpf_float>()
2458 boost::multiprecision::mpf_float result(0.5);
2459 mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::min)() / 64 + 1);
2464 inline boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off>
2465 max_value<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
2467 boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> result(0.5);
2468 mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2473 inline boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off>
2474 min_value<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
2476 boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> result(0.5);
2477 mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2482 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
2483 #ifdef BOOST_MATH_NOEXCEPT
2487 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >::default_precision());
2490 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
2491 #ifdef BOOST_MATH_NOEXCEPT
2495 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >::default_precision());
2499 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >
2500 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
2502 return max_value<boost::multiprecision::mpf_float>().backend();
2506 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >
2507 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
2509 return min_value<boost::multiprecision::mpf_float>().backend();
2513 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off>
2514 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
2516 return max_value<boost::multiprecision::mpf_float>().backend();
2520 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off>
2521 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
2523 return min_value<boost::multiprecision::mpf_float>().backend();
2526 }} // namespace math::tools
2528 } // namespace boost
2533 // numeric_limits [partial] specializations for the types declared in this header:
2535 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2536 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >
2538 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> number_type;
2541 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2543 // min and max values chosen so as to not cause segfaults when calling
2544 // mpf_get_str on 64-bit Linux builds. Possibly we could use larger
2545 // exponent values elsewhere.
2547 static number_type(min)()
2549 initializer.do_nothing();
2550 static std::pair<bool, number_type> value;
2555 mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2557 return value.second;
2559 static number_type(max)()
2561 initializer.do_nothing();
2562 static std::pair<bool, number_type> value;
2567 mpf_mul_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
2569 return value.second;
2571 BOOST_STATIC_CONSTEXPR number_type lowest()
2575 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301L ? 2 : 1));
2576 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
2577 // Have to allow for a possible extra limb inside the gmp data structure:
2578 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 3 + ((GMP_LIMB_BITS * 301L) / 1000L);
2579 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2580 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2581 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2582 BOOST_STATIC_CONSTEXPR int radix = 2;
2583 static number_type epsilon()
2585 initializer.do_nothing();
2586 static std::pair<bool, number_type> value;
2591 mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
2593 return value.second;
2595 // What value should this be????
2596 static number_type round_error()
2598 // returns epsilon/2
2599 initializer.do_nothing();
2600 static std::pair<bool, number_type> value;
2606 return value.second;
2608 BOOST_STATIC_CONSTEXPR long min_exponent = LONG_MIN;
2609 BOOST_STATIC_CONSTEXPR long min_exponent10 = (LONG_MIN / 1000) * 301L;
2610 BOOST_STATIC_CONSTEXPR long max_exponent = LONG_MAX;
2611 BOOST_STATIC_CONSTEXPR long max_exponent10 = (LONG_MAX / 1000) * 301L;
2612 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2613 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2614 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2615 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2616 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2617 BOOST_STATIC_CONSTEXPR number_type infinity() { return number_type(); }
2618 BOOST_STATIC_CONSTEXPR number_type quiet_NaN() { return number_type(); }
2619 BOOST_STATIC_CONSTEXPR number_type signaling_NaN() { return number_type(); }
2620 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(); }
2621 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2622 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
2623 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2624 BOOST_STATIC_CONSTEXPR bool traps = true;
2625 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2626 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate;
2629 struct data_initializer
2633 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::epsilon();
2634 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::round_error();
2635 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::min)();
2636 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::max)();
2638 void do_nothing() const {}
2640 static const data_initializer initializer;
2643 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2644 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;
2646 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2648 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2649 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits;
2650 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2651 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits10;
2652 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2653 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_digits10;
2654 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2655 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_signed;
2656 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2657 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_integer;
2658 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2659 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_exact;
2660 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2661 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::radix;
2662 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2663 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent;
2664 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2665 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent10;
2666 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2667 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent;
2668 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2669 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent10;
2670 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2671 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_infinity;
2672 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2673 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
2674 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2675 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
2676 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2677 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm;
2678 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2679 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm_loss;
2680 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2681 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_iec559;
2682 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2683 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_bounded;
2684 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2685 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_modulo;
2686 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2687 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::traps;
2688 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2689 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::tinyness_before;
2690 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2691 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::round_style;
2695 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2696 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >
2698 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> number_type;
2701 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
2702 static number_type(min)() { return number_type(); }
2703 static number_type(max)() { return number_type(); }
2704 static number_type lowest() { return number_type(); }
2705 BOOST_STATIC_CONSTEXPR int digits = 0;
2706 BOOST_STATIC_CONSTEXPR int digits10 = 0;
2707 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
2708 BOOST_STATIC_CONSTEXPR bool is_signed = false;
2709 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2710 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2711 BOOST_STATIC_CONSTEXPR int radix = 0;
2712 static number_type epsilon() { return number_type(); }
2713 static number_type round_error() { return number_type(); }
2714 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
2715 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
2716 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
2717 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
2718 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2719 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2720 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2721 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2722 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2723 static number_type infinity() { return number_type(); }
2724 static number_type quiet_NaN() { return number_type(); }
2725 static number_type signaling_NaN() { return number_type(); }
2726 static number_type denorm_min() { return number_type(); }
2727 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2728 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
2729 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2730 BOOST_STATIC_CONSTEXPR bool traps = false;
2731 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2732 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate;
2735 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2737 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2738 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits;
2739 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2740 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits10;
2741 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2742 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_digits10;
2743 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2744 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_signed;
2745 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2746 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_integer;
2747 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2748 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_exact;
2749 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2750 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::radix;
2751 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2752 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent;
2753 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2754 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent10;
2755 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2756 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent;
2757 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2758 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent10;
2759 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2760 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_infinity;
2761 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2762 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_quiet_NaN;
2763 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2764 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_signaling_NaN;
2765 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2766 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm;
2767 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2768 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm_loss;
2769 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2770 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_iec559;
2771 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2772 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_bounded;
2773 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2774 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_modulo;
2775 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2776 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::traps;
2777 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2778 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::tinyness_before;
2779 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2780 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::round_style;
2784 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2785 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >
2787 typedef boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> number_type;
2790 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2792 // Largest and smallest numbers are bounded only by available memory, set
2795 static number_type(min)()
2797 return number_type();
2799 static number_type(max)()
2801 return number_type();
2803 static number_type lowest() { return (min)(); }
2804 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
2805 BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
2806 BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3;
2807 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2808 BOOST_STATIC_CONSTEXPR bool is_integer = true;
2809 BOOST_STATIC_CONSTEXPR bool is_exact = true;
2810 BOOST_STATIC_CONSTEXPR int radix = 2;
2811 static number_type epsilon() { return number_type(); }
2812 static number_type round_error() { return number_type(); }
2813 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
2814 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
2815 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
2816 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
2817 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2818 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2819 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2820 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2821 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2822 static number_type infinity() { return number_type(); }
2823 static number_type quiet_NaN() { return number_type(); }
2824 static number_type signaling_NaN() { return number_type(); }
2825 static number_type denorm_min() { return number_type(); }
2826 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2827 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
2828 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2829 BOOST_STATIC_CONSTEXPR bool traps = false;
2830 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2831 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
2834 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2836 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2837 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits;
2838 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2839 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits10;
2840 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2841 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_digits10;
2842 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2843 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_signed;
2844 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2845 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_integer;
2846 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2847 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_exact;
2848 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2849 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::radix;
2850 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2851 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent;
2852 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2853 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent10;
2854 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2855 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent;
2856 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2857 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent10;
2858 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2859 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_infinity;
2860 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2861 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_quiet_NaN;
2862 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2863 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_signaling_NaN;
2864 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2865 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm;
2866 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2867 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm_loss;
2868 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2869 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_iec559;
2870 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2871 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_bounded;
2872 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2873 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_modulo;
2874 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2875 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::traps;
2876 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2877 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::tinyness_before;
2878 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2879 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::round_style;
2883 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2884 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >
2886 typedef boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> number_type;
2889 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2891 // Largest and smallest numbers are bounded only by available memory, set
2894 static number_type(min)()
2896 return number_type();
2898 static number_type(max)()
2900 return number_type();
2902 static number_type lowest() { return (min)(); }
2903 // Digits are unbounded, use zero for now:
2904 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
2905 BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
2906 BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3;
2907 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2908 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2909 BOOST_STATIC_CONSTEXPR bool is_exact = true;
2910 BOOST_STATIC_CONSTEXPR int radix = 2;
2911 static number_type epsilon() { return number_type(); }
2912 static number_type round_error() { return number_type(); }
2913 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
2914 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
2915 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
2916 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
2917 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2918 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2919 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2920 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2921 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2922 static number_type infinity() { return number_type(); }
2923 static number_type quiet_NaN() { return number_type(); }
2924 static number_type signaling_NaN() { return number_type(); }
2925 static number_type denorm_min() { return number_type(); }
2926 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2927 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
2928 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2929 BOOST_STATIC_CONSTEXPR bool traps = false;
2930 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2931 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
2934 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2936 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2937 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits;
2938 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2939 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits10;
2940 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2941 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_digits10;
2942 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2943 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_signed;
2944 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2945 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_integer;
2946 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2947 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_exact;
2948 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2949 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::radix;
2950 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2951 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent;
2952 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2953 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent10;
2954 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2955 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent;
2956 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2957 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent10;
2958 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2959 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_infinity;
2960 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2961 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_quiet_NaN;
2962 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2963 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_signaling_NaN;
2964 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2965 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm;
2966 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2967 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm_loss;
2968 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2969 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_iec559;
2970 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2971 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_bounded;
2972 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2973 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_modulo;
2974 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2975 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::traps;
2976 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2977 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::tinyness_before;
2978 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2979 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::round_style;
2984 #pragma warning(pop)