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_BN_MPFR_HPP
7 #define BOOST_MATH_BN_MPFR_HPP
9 #include <boost/multiprecision/number.hpp>
10 #include <boost/multiprecision/debug_adaptor.hpp>
11 #include <boost/multiprecision/gmp.hpp>
12 #include <boost/math/special_functions/fpclassify.hpp>
13 #include <boost/cstdint.hpp>
14 #include <boost/multiprecision/detail/big_lanczos.hpp>
15 #include <boost/multiprecision/detail/digits.hpp>
20 #ifndef BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION
21 #define BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION 20
25 namespace multiprecision {
27 enum mpfr_allocation_type
35 template <unsigned digits10, mpfr_allocation_type AllocationType = allocate_dynamic>
36 struct mpfr_float_backend;
39 struct mpfr_float_backend<0, allocate_stack>;
41 } // namespace backends
43 template <unsigned digits10, mpfr_allocation_type AllocationType>
44 struct number_category<backends::mpfr_float_backend<digits10, AllocationType> > : public mpl::int_<number_kind_floating_point>
57 ~initializer() { mpfr_free_cache(); }
58 void force_instantiate() const {}
60 static const initializer init;
61 static void force_instantiate() { init.force_instantiate(); }
65 typename mpfr_cleanup<b>::initializer const mpfr_cleanup<b>::init;
67 inline void mpfr_copy_precision(mpfr_t dest, const mpfr_t src)
69 mpfr_prec_t p_dest = mpfr_get_prec(dest);
70 mpfr_prec_t p_src = mpfr_get_prec(src);
72 mpfr_set_prec(dest, p_src);
74 inline void mpfr_copy_precision(mpfr_t dest, const mpfr_t src1, const mpfr_t src2)
76 mpfr_prec_t p_dest = mpfr_get_prec(dest);
77 mpfr_prec_t p_src1 = mpfr_get_prec(src1);
78 mpfr_prec_t p_src2 = mpfr_get_prec(src2);
82 mpfr_set_prec(dest, p_src1);
85 template <unsigned digits10, mpfr_allocation_type AllocationType>
86 struct mpfr_float_imp;
88 template <unsigned digits10>
89 struct mpfr_float_imp<digits10, allocate_dynamic>
91 #ifdef BOOST_HAS_LONG_LONG
92 typedef mpl::list<long, boost::long_long_type> signed_types;
93 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
95 typedef mpl::list<long> signed_types;
96 typedef mpl::list<unsigned long> unsigned_types;
98 typedef mpl::list<double, long double> float_types;
99 typedef long exponent_type;
103 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
104 mpfr_set_ui(m_data, 0u, GMP_RNDN);
106 mpfr_float_imp(unsigned digits2)
108 mpfr_init2(m_data, digits2);
109 mpfr_set_ui(m_data, 0u, GMP_RNDN);
112 mpfr_float_imp(const mpfr_float_imp& o)
114 mpfr_init2(m_data, mpfr_get_prec(o.m_data));
115 if (o.m_data[0]._mpfr_d)
116 mpfr_set(m_data, o.m_data, GMP_RNDN);
118 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
119 mpfr_float_imp(mpfr_float_imp&& o) BOOST_NOEXCEPT
121 m_data[0] = o.m_data[0];
122 o.m_data[0]._mpfr_d = 0;
125 mpfr_float_imp& operator=(const mpfr_float_imp& o)
127 if ((o.m_data[0]._mpfr_d) && (this != &o))
129 if (m_data[0]._mpfr_d == 0)
130 mpfr_init2(m_data, mpfr_get_prec(o.m_data));
131 mpfr_set(m_data, o.m_data, GMP_RNDN);
135 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
136 mpfr_float_imp& operator=(mpfr_float_imp&& o) BOOST_NOEXCEPT
138 mpfr_swap(m_data, o.m_data);
142 #ifdef BOOST_HAS_LONG_LONG
143 #ifdef _MPFR_H_HAVE_INTMAX_T
144 mpfr_float_imp& operator=(boost::ulong_long_type i)
146 if (m_data[0]._mpfr_d == 0)
147 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
148 mpfr_set_uj(m_data, i, GMP_RNDN);
151 mpfr_float_imp& operator=(boost::long_long_type i)
153 if (m_data[0]._mpfr_d == 0)
154 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
155 mpfr_set_sj(m_data, i, GMP_RNDN);
159 mpfr_float_imp& operator=(boost::ulong_long_type i)
161 if (m_data[0]._mpfr_d == 0)
162 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
163 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
166 mpfr_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), mpfr_get_prec(m_data)));
167 mpfr_set_ui(m_data, 0, GMP_RNDN);
170 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
172 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
173 mpfr_add(m_data, m_data, t, GMP_RNDN);
174 shift += std::numeric_limits<unsigned long>::digits;
175 i >>= std::numeric_limits<unsigned long>::digits;
180 mpfr_float_imp& operator=(boost::long_long_type i)
182 if (m_data[0]._mpfr_d == 0)
183 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
185 *this = boost::multiprecision::detail::unsigned_abs(i);
187 mpfr_neg(m_data, m_data, GMP_RNDN);
192 mpfr_float_imp& operator=(unsigned long i)
194 if (m_data[0]._mpfr_d == 0)
195 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
196 mpfr_set_ui(m_data, i, GMP_RNDN);
199 mpfr_float_imp& operator=(long i)
201 if (m_data[0]._mpfr_d == 0)
202 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
203 mpfr_set_si(m_data, i, GMP_RNDN);
206 mpfr_float_imp& operator=(double d)
208 if (m_data[0]._mpfr_d == 0)
209 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
210 mpfr_set_d(m_data, d, GMP_RNDN);
213 mpfr_float_imp& operator=(long double a)
215 if (m_data[0]._mpfr_d == 0)
216 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
217 mpfr_set_ld(m_data, a, GMP_RNDN);
220 mpfr_float_imp& operator=(const char* s)
222 if (m_data[0]._mpfr_d == 0)
223 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
224 if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
226 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
230 void swap(mpfr_float_imp& o) BOOST_NOEXCEPT
232 mpfr_swap(m_data, o.m_data);
234 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
236 BOOST_ASSERT(m_data[0]._mpfr_d);
238 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
239 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
241 std::streamsize org_digits(digits);
243 if (scientific && digits)
248 if (mpfr_inf_p(m_data))
250 if (mpfr_sgn(m_data) < 0)
252 else if (f & std::ios_base::showpos)
258 if (mpfr_nan_p(m_data))
263 if (mpfr_zero_p(m_data))
270 char* ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
271 --e; // To match with what our formatter expects.
272 if (fixed && e != -1)
274 // Oops we actually need a different number of digits to what we asked for:
279 // We need to get *all* the digits and then possibly round up,
280 // we end up with either "0" or "1" as the result.
281 ps = mpfr_get_str(0, &e, 10, 0, m_data, GMP_RNDN);
283 unsigned offset = *ps == '-' ? 1 : 0;
284 if (ps[offset] > '5')
290 else if (ps[offset] == '5')
292 unsigned i = offset + 1;
293 bool round_up = false;
324 ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
325 --e; // To match with what our formatter expects.
328 // in some cases, when we ask for more digits of precision, it will
329 // change the number of digits to the left of the decimal, if that
330 // happens, account for it here.
331 // example: cout << fixed << setprecision(3) << mpf_float_50("99.9809")
333 ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
334 --e; // To match with what our formatter expects.
339 ps = mpfr_get_str(0, &e, 10, 1, m_data, GMP_RNDN);
341 unsigned offset = *ps == '-' ? 1 : 0;
346 result = ps ? ps : "0";
350 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
353 ~mpfr_float_imp() BOOST_NOEXCEPT
355 if (m_data[0]._mpfr_d)
357 detail::mpfr_cleanup<true>::force_instantiate();
359 void negate() BOOST_NOEXCEPT
361 BOOST_ASSERT(m_data[0]._mpfr_d);
362 mpfr_neg(m_data, m_data, GMP_RNDN);
364 template <mpfr_allocation_type AllocationType>
365 int compare(const mpfr_float_backend<digits10, AllocationType>& o) const BOOST_NOEXCEPT
367 BOOST_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d);
368 return mpfr_cmp(m_data, o.m_data);
370 int compare(long i) const BOOST_NOEXCEPT
372 BOOST_ASSERT(m_data[0]._mpfr_d);
373 return mpfr_cmp_si(m_data, i);
375 int compare(unsigned long i) const BOOST_NOEXCEPT
377 BOOST_ASSERT(m_data[0]._mpfr_d);
378 return mpfr_cmp_ui(m_data, i);
381 int compare(V v) const BOOST_NOEXCEPT
383 mpfr_float_backend<digits10, allocate_dynamic> d(0uL, mpfr_get_prec(m_data));
387 mpfr_t& data() BOOST_NOEXCEPT
389 BOOST_ASSERT(m_data[0]._mpfr_d);
392 const mpfr_t& data() const BOOST_NOEXCEPT
394 BOOST_ASSERT(m_data[0]._mpfr_d);
400 static unsigned& get_default_precision() BOOST_NOEXCEPT
402 static unsigned val = BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION;
408 #pragma warning(push)
409 #pragma warning(disable : 4127) // Conditional expression is constant
412 template <unsigned digits10>
413 struct mpfr_float_imp<digits10, allocate_stack>
415 #ifdef BOOST_HAS_LONG_LONG
416 typedef mpl::list<long, boost::long_long_type> signed_types;
417 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
419 typedef mpl::list<long> signed_types;
420 typedef mpl::list<unsigned long> unsigned_types;
422 typedef mpl::list<double, long double> float_types;
423 typedef long exponent_type;
425 static const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u);
426 static const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t);
428 ~mpfr_float_imp() BOOST_NOEXCEPT
430 detail::mpfr_cleanup<true>::force_instantiate();
434 mpfr_custom_init(m_buffer, digits2);
435 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
436 mpfr_set_ui(m_data, 0u, GMP_RNDN);
439 mpfr_float_imp(const mpfr_float_imp& o)
441 mpfr_custom_init(m_buffer, digits2);
442 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
443 mpfr_set(m_data, o.m_data, GMP_RNDN);
445 mpfr_float_imp& operator=(const mpfr_float_imp& o)
447 mpfr_set(m_data, o.m_data, GMP_RNDN);
450 #ifdef BOOST_HAS_LONG_LONG
451 #ifdef _MPFR_H_HAVE_INTMAX_T
452 mpfr_float_imp& operator=(boost::ulong_long_type i)
454 mpfr_set_uj(m_data, i, GMP_RNDN);
457 mpfr_float_imp& operator=(boost::long_long_type i)
459 mpfr_set_sj(m_data, i, GMP_RNDN);
463 mpfr_float_imp& operator=(boost::ulong_long_type i)
465 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL);
468 mp_limb_t t_limbs[limb_count];
469 mpfr_custom_init(t_limbs, digits2);
470 mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
471 mpfr_set_ui(m_data, 0, GMP_RNDN);
474 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
476 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
477 mpfr_add(m_data, m_data, t, GMP_RNDN);
478 shift += std::numeric_limits<unsigned long>::digits;
479 i >>= std::numeric_limits<unsigned long>::digits;
483 mpfr_float_imp& operator=(boost::long_long_type i)
486 *this = boost::multiprecision::detail::unsigned_abs(i);
488 mpfr_neg(m_data, m_data, GMP_RNDN);
493 mpfr_float_imp& operator=(unsigned long i)
495 mpfr_set_ui(m_data, i, GMP_RNDN);
498 mpfr_float_imp& operator=(long i)
500 mpfr_set_si(m_data, i, GMP_RNDN);
503 mpfr_float_imp& operator=(double d)
505 mpfr_set_d(m_data, d, GMP_RNDN);
508 mpfr_float_imp& operator=(long double a)
510 mpfr_set_ld(m_data, a, GMP_RNDN);
513 mpfr_float_imp& operator=(const char* s)
515 if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
517 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
521 void swap(mpfr_float_imp& o) BOOST_NOEXCEPT
523 // We have to swap by copying:
524 mpfr_float_imp t(*this);
528 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
530 BOOST_ASSERT(m_data[0]._mpfr_d);
532 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
533 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
535 std::streamsize org_digits(digits);
537 if (scientific && digits)
542 if (mpfr_inf_p(m_data))
544 if (mpfr_sgn(m_data) < 0)
546 else if (f & std::ios_base::showpos)
552 if (mpfr_nan_p(m_data))
557 if (mpfr_zero_p(m_data))
564 char* ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
565 --e; // To match with what our formatter expects.
566 if (fixed && e != -1)
568 // Oops we actually need a different number of digits to what we asked for:
573 // We need to get *all* the digits and then possibly round up,
574 // we end up with either "0" or "1" as the result.
575 ps = mpfr_get_str(0, &e, 10, 0, m_data, GMP_RNDN);
577 unsigned offset = *ps == '-' ? 1 : 0;
578 if (ps[offset] > '5')
584 else if (ps[offset] == '5')
586 unsigned i = offset + 1;
587 bool round_up = false;
616 ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
617 --e; // To match with what our formatter expects.
621 ps = mpfr_get_str(0, &e, 10, 1, m_data, GMP_RNDN);
623 unsigned offset = *ps == '-' ? 1 : 0;
628 result = ps ? ps : "0";
632 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
635 void negate() BOOST_NOEXCEPT
637 mpfr_neg(m_data, m_data, GMP_RNDN);
639 template <mpfr_allocation_type AllocationType>
640 int compare(const mpfr_float_backend<digits10, AllocationType>& o) const BOOST_NOEXCEPT
642 return mpfr_cmp(m_data, o.m_data);
644 int compare(long i) const BOOST_NOEXCEPT
646 return mpfr_cmp_si(m_data, i);
648 int compare(unsigned long i) const BOOST_NOEXCEPT
650 return mpfr_cmp_ui(m_data, i);
653 int compare(V v) const BOOST_NOEXCEPT
655 mpfr_float_backend<digits10, allocate_stack> d;
659 mpfr_t& data() BOOST_NOEXCEPT
663 const mpfr_t& data() const BOOST_NOEXCEPT
670 mp_limb_t m_buffer[limb_count];
677 } // namespace detail
679 template <unsigned digits10, mpfr_allocation_type AllocationType>
680 struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
682 mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
683 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
684 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
685 mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o))
688 template <unsigned D, mpfr_allocation_type AT>
689 mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename enable_if_c<D <= digits10>::type* = 0)
690 : detail::mpfr_float_imp<digits10, AllocationType>()
692 mpfr_set(this->m_data, val.data(), GMP_RNDN);
694 template <unsigned D, mpfr_allocation_type AT>
695 explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename disable_if_c<D <= digits10>::type* = 0)
696 : detail::mpfr_float_imp<digits10, AllocationType>()
698 mpfr_set(this->m_data, val.data(), GMP_RNDN);
700 template <unsigned D>
701 mpfr_float_backend(const gmp_float<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
702 : detail::mpfr_float_imp<digits10, AllocationType>()
704 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
706 template <unsigned D>
707 mpfr_float_backend(const gmp_float<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
708 : detail::mpfr_float_imp<digits10, AllocationType>()
710 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
712 mpfr_float_backend(const gmp_int& val)
713 : detail::mpfr_float_imp<digits10, AllocationType>()
715 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
717 mpfr_float_backend(const gmp_rational& val)
718 : detail::mpfr_float_imp<digits10, AllocationType>()
720 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
722 mpfr_float_backend(const mpfr_t val)
723 : detail::mpfr_float_imp<digits10, AllocationType>()
725 mpfr_set(this->m_data, val, GMP_RNDN);
727 mpfr_float_backend(const mpf_t val)
728 : detail::mpfr_float_imp<digits10, AllocationType>()
730 mpfr_set_f(this->m_data, val, GMP_RNDN);
732 mpfr_float_backend(const mpz_t val)
733 : detail::mpfr_float_imp<digits10, AllocationType>()
735 mpfr_set_z(this->m_data, val, GMP_RNDN);
737 mpfr_float_backend(const mpq_t val)
738 : detail::mpfr_float_imp<digits10, AllocationType>()
740 mpfr_set_q(this->m_data, val, GMP_RNDN);
742 // Construction with precision: we ignore the precision here.
744 mpfr_float_backend(const V& o, unsigned)
748 mpfr_float_backend& operator=(const mpfr_float_backend& o)
750 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
753 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
754 mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT
756 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
761 mpfr_float_backend& operator=(const V& v)
763 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
766 mpfr_float_backend& operator=(const mpfr_t val)
768 if (this->m_data[0]._mpfr_d == 0)
769 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
770 mpfr_set(this->m_data, val, GMP_RNDN);
773 mpfr_float_backend& operator=(const mpf_t val)
775 if (this->m_data[0]._mpfr_d == 0)
776 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
777 mpfr_set_f(this->m_data, val, GMP_RNDN);
780 mpfr_float_backend& operator=(const mpz_t val)
782 if (this->m_data[0]._mpfr_d == 0)
783 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
784 mpfr_set_z(this->m_data, val, GMP_RNDN);
787 mpfr_float_backend& operator=(const mpq_t val)
789 if (this->m_data[0]._mpfr_d == 0)
790 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
791 mpfr_set_q(this->m_data, val, GMP_RNDN);
794 // We don't change our precision here, this is a fixed precision type:
795 template <unsigned D, mpfr_allocation_type AT>
796 mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
798 if (this->m_data[0]._mpfr_d == 0)
799 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
800 mpfr_set(this->m_data, val.data(), GMP_RNDN);
803 template <unsigned D>
804 mpfr_float_backend& operator=(const gmp_float<D>& val)
806 if (this->m_data[0]._mpfr_d == 0)
807 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
808 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
811 mpfr_float_backend& operator=(const gmp_int& val)
813 if (this->m_data[0]._mpfr_d == 0)
814 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
815 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
818 mpfr_float_backend& operator=(const gmp_rational& val)
820 if (this->m_data[0]._mpfr_d == 0)
821 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
822 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
828 struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
830 mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
831 mpfr_float_backend(const mpfr_t val)
832 : detail::mpfr_float_imp<0, allocate_dynamic>((unsigned)mpfr_get_prec(val))
834 mpfr_set(this->m_data, val, GMP_RNDN);
836 mpfr_float_backend(const mpf_t val)
837 : detail::mpfr_float_imp<0, allocate_dynamic>((unsigned)mpf_get_prec(val))
839 mpfr_set_f(this->m_data, val, GMP_RNDN);
841 mpfr_float_backend(const mpz_t val)
842 : detail::mpfr_float_imp<0, allocate_dynamic>()
844 mpfr_set_z(this->m_data, val, GMP_RNDN);
846 mpfr_float_backend(const mpq_t val)
847 : detail::mpfr_float_imp<0, allocate_dynamic>()
849 mpfr_set_q(this->m_data, val, GMP_RNDN);
851 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
852 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
853 mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o))
857 mpfr_float_backend(const V& o, unsigned digits10)
858 : detail::mpfr_float_imp<0, allocate_dynamic>(multiprecision::detail::digits10_2_2(digits10))
862 #ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
863 mpfr_float_backend(const std::string_view& o, unsigned digits10)
864 : detail::mpfr_float_imp<0, allocate_dynamic>(multiprecision::detail::digits10_2_2(digits10))
870 template <unsigned D>
871 mpfr_float_backend(const gmp_float<D>& val, unsigned digits10)
872 : detail::mpfr_float_imp<0, allocate_dynamic>(multiprecision::detail::digits10_2_2(digits10))
874 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
876 template <unsigned D>
877 mpfr_float_backend(const mpfr_float_backend<D>& val, unsigned digits10)
878 : detail::mpfr_float_imp<0, allocate_dynamic>(multiprecision::detail::digits10_2_2(digits10))
880 mpfr_set(this->m_data, val.data(), GMP_RNDN);
882 template <unsigned D>
883 mpfr_float_backend(const mpfr_float_backend<D>& val)
884 : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val.data()))
886 mpfr_set(this->m_data, val.data(), GMP_RNDN);
888 template <unsigned D>
889 mpfr_float_backend(const gmp_float<D>& val)
890 : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val.data()))
892 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
894 mpfr_float_backend(const gmp_int& val)
895 : detail::mpfr_float_imp<0, allocate_dynamic>()
897 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
899 mpfr_float_backend(const gmp_rational& val)
900 : detail::mpfr_float_imp<0, allocate_dynamic>()
902 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
905 mpfr_float_backend& operator=(const mpfr_float_backend& o)
909 if (this->m_data[0]._mpfr_d == 0)
910 mpfr_init2(this->m_data, mpfr_get_prec(o.data()));
912 detail::mpfr_copy_precision(this->m_data, o.data());
913 mpfr_set(this->m_data, o.data(), GMP_RNDN);
917 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
918 mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT
920 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o);
925 mpfr_float_backend& operator=(const V& v)
927 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
930 mpfr_float_backend& operator=(const mpfr_t val)
932 if (this->m_data[0]._mpfr_d == 0)
933 mpfr_init2(this->m_data, mpfr_get_prec(val));
935 mpfr_set_prec(this->m_data, mpfr_get_prec(val));
936 mpfr_set(this->m_data, val, GMP_RNDN);
939 mpfr_float_backend& operator=(const mpf_t val)
941 if (this->m_data[0]._mpfr_d == 0)
942 mpfr_init2(this->m_data, (mpfr_prec_t)mpf_get_prec(val));
944 mpfr_set_prec(this->m_data, (unsigned)mpf_get_prec(val));
945 mpfr_set_f(this->m_data, val, GMP_RNDN);
948 mpfr_float_backend& operator=(const mpz_t val)
950 if (this->m_data[0]._mpfr_d == 0)
951 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
952 mpfr_set_z(this->m_data, val, GMP_RNDN);
955 mpfr_float_backend& operator=(const mpq_t val)
957 if (this->m_data[0]._mpfr_d == 0)
958 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
959 mpfr_set_q(this->m_data, val, GMP_RNDN);
962 template <unsigned D>
963 mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
965 if (this->m_data[0]._mpfr_d == 0)
966 mpfr_init2(this->m_data, mpfr_get_prec(val.data()));
968 mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
969 mpfr_set(this->m_data, val.data(), GMP_RNDN);
972 template <unsigned D>
973 mpfr_float_backend& operator=(const gmp_float<D>& val)
975 if (this->m_data[0]._mpfr_d == 0)
976 mpfr_init2(this->m_data, mpf_get_prec(val.data()));
978 mpfr_set_prec(this->m_data, mpf_get_prec(val.data()));
979 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
982 mpfr_float_backend& operator=(const gmp_int& val)
984 if (this->m_data[0]._mpfr_d == 0)
985 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
986 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
989 mpfr_float_backend& operator=(const gmp_rational& val)
991 if (this->m_data[0]._mpfr_d == 0)
992 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
993 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
996 static unsigned default_precision() BOOST_NOEXCEPT
998 return get_default_precision();
1000 static void default_precision(unsigned v) BOOST_NOEXCEPT
1002 get_default_precision() = v;
1004 unsigned precision() const BOOST_NOEXCEPT
1006 return multiprecision::detail::digits2_2_10(mpfr_get_prec(this->m_data));
1008 void precision(unsigned digits10) BOOST_NOEXCEPT
1010 mpfr_prec_round(this->m_data, multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
1014 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1015 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
1017 return a.compare(b) == 0;
1019 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1020 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
1022 return a.compare(b) < 0;
1024 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1025 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
1027 return a.compare(b) > 0;
1030 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1031 inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1033 mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
1035 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1036 inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1038 mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
1040 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1041 inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1043 if ((void*)&o == (void*)&result)
1044 mpfr_sqr(result.data(), o.data(), GMP_RNDN);
1046 mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
1048 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1049 inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1051 mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
1053 template <unsigned digits10, mpfr_allocation_type AllocationType>
1054 inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1056 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1058 template <unsigned digits10, mpfr_allocation_type AllocationType>
1059 inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1061 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
1063 template <unsigned digits10, mpfr_allocation_type AllocationType>
1064 inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1066 mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
1068 template <unsigned digits10, mpfr_allocation_type AllocationType>
1069 inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1071 mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
1073 template <unsigned digits10, mpfr_allocation_type AllocationType>
1074 inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
1077 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1079 mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1081 template <unsigned digits10, mpfr_allocation_type AllocationType>
1082 inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
1085 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
1087 mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1089 template <unsigned digits10, mpfr_allocation_type AllocationType>
1090 inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
1092 mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1094 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1096 template <unsigned digits10, mpfr_allocation_type AllocationType>
1097 inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
1099 mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1101 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1104 // Specialised 3 arg versions of the basic operators:
1106 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
1107 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
1109 mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
1111 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1112 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1114 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1116 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1117 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1120 mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1122 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1124 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1125 inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1127 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1129 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1130 inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1134 mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1135 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1138 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1140 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
1141 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
1143 mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
1145 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1146 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1148 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1150 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1151 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1154 mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1156 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1158 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1159 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1161 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1163 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1164 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1168 mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1169 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1172 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1175 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
1176 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
1178 if ((void*)&x == (void*)&y)
1179 mpfr_sqr(a.data(), x.data(), GMP_RNDN);
1181 mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
1183 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1184 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1186 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1188 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1189 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1193 mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1197 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1199 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1200 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1202 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1204 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1205 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1209 mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1210 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1213 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1216 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
1217 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
1219 mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
1221 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1222 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1224 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1226 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1227 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1231 mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1235 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1237 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1238 inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1240 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1242 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1243 inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1247 mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1248 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1251 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1254 template <unsigned digits10, mpfr_allocation_type AllocationType>
1255 inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1257 return 0 != mpfr_zero_p(val.data());
1259 template <unsigned digits10, mpfr_allocation_type AllocationType>
1260 inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1262 return mpfr_sgn(val.data());
1265 template <unsigned digits10, mpfr_allocation_type AllocationType>
1266 inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1268 if (mpfr_nan_p(val.data()))
1270 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1272 *result = mpfr_get_ui(val.data(), GMP_RNDZ);
1274 template <unsigned digits10, mpfr_allocation_type AllocationType>
1275 inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1277 if (mpfr_nan_p(val.data()))
1279 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1281 *result = mpfr_get_si(val.data(), GMP_RNDZ);
1283 #ifdef _MPFR_H_HAVE_INTMAX_T
1284 template <unsigned digits10, mpfr_allocation_type AllocationType>
1285 inline void eval_convert_to(boost::ulong_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val)
1287 if (mpfr_nan_p(val.data()))
1289 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1291 *result = mpfr_get_uj(val.data(), GMP_RNDZ);
1293 template <unsigned digits10, mpfr_allocation_type AllocationType>
1294 inline void eval_convert_to(boost::long_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val)
1296 if (mpfr_nan_p(val.data()))
1298 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1300 *result = mpfr_get_sj(val.data(), GMP_RNDZ);
1303 template <unsigned digits10, mpfr_allocation_type AllocationType>
1304 inline void eval_convert_to(float* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1306 *result = mpfr_get_flt(val.data(), GMP_RNDN);
1308 template <unsigned digits10, mpfr_allocation_type AllocationType>
1309 inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1311 *result = mpfr_get_d(val.data(), GMP_RNDN);
1313 template <unsigned digits10, mpfr_allocation_type AllocationType>
1314 inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1316 *result = mpfr_get_ld(val.data(), GMP_RNDN);
1320 // Native non-member operations:
1322 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1323 inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1325 mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
1328 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1329 inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1331 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1334 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1335 inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1337 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1339 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1340 inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1342 mpfr_ceil(result.data(), val.data());
1344 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1345 inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1347 mpfr_floor(result.data(), val.data());
1349 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1350 inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1352 mpfr_trunc(result.data(), val.data());
1354 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1355 inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
1358 mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN);
1360 mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN);
1364 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1365 inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
1368 mpfr_get_d_2exp(&v, val.data(), GMP_RNDN);
1370 eval_ldexp(result, val, -v);
1372 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1373 inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
1375 mpfr_get_d_2exp(e, val.data(), GMP_RNDN);
1376 return eval_ldexp(result, val, -*e);
1379 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1380 inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) BOOST_NOEXCEPT
1382 return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
1385 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1386 inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
1388 if (mpfr_zero_p(b.data()) && mpfr_integer_p(e.data()) && (mpfr_signbit(e.data()) == 0) && mpfr_fits_ulong_p(e.data(), GMP_RNDN) && (mpfr_get_ui(e.data(), GMP_RNDN) & 1))
1390 mpfr_set(result.data(), b.data(), GMP_RNDN);
1393 mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1398 // The enable_if usage below doesn't work with msvc - but only when
1399 // certain other enable_if usages are defined first. It's a capricious
1400 // and rather annoying compiler bug in other words....
1402 #define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10)&&
1404 #define BOOST_MP_ENABLE_IF_WORKAROUND
1407 template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1408 inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long))> > >::type
1409 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
1411 mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
1414 template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1415 inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long))> > >::type
1416 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
1418 mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
1421 #undef BOOST_MP_ENABLE_IF_WORKAROUND
1423 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1424 inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1426 mpfr_exp(result.data(), arg.data(), GMP_RNDN);
1429 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1430 inline void eval_exp2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1432 mpfr_exp2(result.data(), arg.data(), GMP_RNDN);
1435 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1436 inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1438 mpfr_log(result.data(), arg.data(), GMP_RNDN);
1441 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1442 inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1444 mpfr_log10(result.data(), arg.data(), GMP_RNDN);
1447 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1448 inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1450 mpfr_sin(result.data(), arg.data(), GMP_RNDN);
1453 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1454 inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1456 mpfr_cos(result.data(), arg.data(), GMP_RNDN);
1459 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1460 inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1462 mpfr_tan(result.data(), arg.data(), GMP_RNDN);
1465 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1466 inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1468 mpfr_asin(result.data(), arg.data(), GMP_RNDN);
1471 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1472 inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1474 mpfr_acos(result.data(), arg.data(), GMP_RNDN);
1477 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1478 inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1480 mpfr_atan(result.data(), arg.data(), GMP_RNDN);
1483 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1484 inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
1486 mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
1489 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1490 inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1492 mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
1495 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1496 inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1498 mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
1501 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1502 inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1504 mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
1507 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1508 inline void eval_log2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1510 mpfr_log2(result.data(), arg.data(), GMP_RNDN);
1513 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1514 inline void eval_modf(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg, mpfr_float_backend<Digits10, AllocateType>* pipart)
1518 mpfr_float_backend<Digits10, AllocateType> ipart;
1519 mpfr_modf(ipart.data(), result.data(), arg.data(), GMP_RNDN);
1523 mpfr_modf(pipart->data(), result.data(), arg.data(), GMP_RNDN);
1526 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1527 inline void eval_remainder(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1529 mpfr_remainder(result.data(), a.data(), b.data(), GMP_RNDN);
1531 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1532 inline void eval_remquo(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, int* pi)
1535 mpfr_remquo(result.data(), &l, a.data(), b.data(), GMP_RNDN);
1540 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1541 inline void eval_fmod(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1543 mpfr_fmod(result.data(), a.data(), b.data(), GMP_RNDN);
1546 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1547 inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1549 mpfr_fma(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1552 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1553 inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
1555 mpfr_fma(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1558 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1559 inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1561 mpfr_fms(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1565 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1566 inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
1568 mpfr_fms(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1571 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1572 inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const mpfr_float_backend<Digits10, AllocateType>& arg)
1574 return (arg.data()[0]._mpfr_sign < 0) ? 1 : 0;
1577 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1578 inline std::size_t hash_value(const mpfr_float_backend<Digits10, AllocateType>& val)
1580 std::size_t result = 0;
1581 std::size_t len = val.data()[0]._mpfr_prec / mp_bits_per_limb;
1582 if (val.data()[0]._mpfr_prec % mp_bits_per_limb)
1584 for (std::size_t i = 0; i < len; ++i)
1585 boost::hash_combine(result, val.data()[0]._mpfr_d[i]);
1586 boost::hash_combine(result, val.data()[0]._mpfr_exp);
1587 boost::hash_combine(result, val.data()[0]._mpfr_sign);
1591 } // namespace backends
1593 #ifdef BOOST_NO_SFINAE_EXPR
1597 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1598 struct is_explicitly_convertible<backends::mpfr_float_backend<D1, A1>, backends::mpfr_float_backend<D2, A2> > : public mpl::true_
1601 } // namespace detail
1607 struct is_variable_precision<backends::mpfr_float_backend<0> > : public true_type
1609 } // namespace detail
1612 struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>
1615 using boost::multiprecision::backends::mpfr_float_backend;
1617 typedef number<mpfr_float_backend<50> > mpfr_float_50;
1618 typedef number<mpfr_float_backend<100> > mpfr_float_100;
1619 typedef number<mpfr_float_backend<500> > mpfr_float_500;
1620 typedef number<mpfr_float_backend<1000> > mpfr_float_1000;
1621 typedef number<mpfr_float_backend<0> > mpfr_float;
1623 typedef number<mpfr_float_backend<50, allocate_stack> > static_mpfr_float_50;
1624 typedef number<mpfr_float_backend<100, allocate_stack> > static_mpfr_float_100;
1626 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1627 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& b)
1629 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(-a) : a;
1632 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1633 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& b)
1635 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>(-a) : a;
1638 } // namespace multiprecision
1642 using boost::multiprecision::copysign;
1643 using boost::multiprecision::signbit;
1648 inline int digits<boost::multiprecision::mpfr_float>()
1649 #ifdef BOOST_MATH_NOEXCEPT
1653 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::default_precision());
1656 inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
1657 #ifdef BOOST_MATH_NOEXCEPT
1661 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::default_precision());
1665 inline boost::multiprecision::mpfr_float
1666 max_value<boost::multiprecision::mpfr_float>()
1668 boost::multiprecision::mpfr_float result(0.5);
1669 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
1670 BOOST_ASSERT(mpfr_number_p(result.backend().data()));
1675 inline boost::multiprecision::mpfr_float
1676 min_value<boost::multiprecision::mpfr_float>()
1678 boost::multiprecision::mpfr_float result(0.5);
1679 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
1680 BOOST_ASSERT(mpfr_number_p(result.backend().data()));
1685 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
1686 max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
1688 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
1689 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
1690 BOOST_ASSERT(mpfr_number_p(result.backend().data()));
1695 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
1696 min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
1698 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
1699 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
1700 BOOST_ASSERT(mpfr_number_p(result.backend().data()));
1705 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
1706 #ifdef BOOST_MATH_NOEXCEPT
1710 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision());
1713 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
1714 #ifdef BOOST_MATH_NOEXCEPT
1718 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision());
1722 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
1723 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
1725 return max_value<boost::multiprecision::mpfr_float>().backend();
1729 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
1730 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
1732 return min_value<boost::multiprecision::mpfr_float>().backend();
1736 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
1737 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
1739 return max_value<boost::multiprecision::mpfr_float>().backend();
1743 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
1744 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
1746 return min_value<boost::multiprecision::mpfr_float>().backend();
1749 } // namespace tools
1751 namespace constants { namespace detail {
1756 struct constant_ln_two;
1758 struct constant_euler;
1760 struct constant_catalan;
1764 template <class T, int N>
1765 struct mpfr_constant_initializer
1767 static void force_instantiate()
1769 init.force_instantiate();
1777 T::get(mpl::int_<N>());
1779 void force_instantiate() const {}
1781 static const initializer init;
1784 template <class T, int N>
1785 typename mpfr_constant_initializer<T, N>::initializer const mpfr_constant_initializer<T, N>::init;
1787 } // namespace detail
1789 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1790 struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
1792 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
1794 static inline const result_type& get(const mpl::int_<N>&)
1796 detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
1797 static result_type result;
1798 static bool has_init = false;
1801 mpfr_const_pi(result.backend().data(), GMP_RNDN);
1806 static inline const result_type get(const mpl::int_<0>&)
1809 mpfr_const_pi(result.backend().data(), GMP_RNDN);
1813 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1814 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
1816 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
1818 static inline const result_type& get(const mpl::int_<N>&)
1820 detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
1821 static result_type result;
1822 static bool init = false;
1825 mpfr_const_log2(result.backend().data(), GMP_RNDN);
1830 static inline const result_type get(const mpl::int_<0>&)
1833 mpfr_const_log2(result.backend().data(), GMP_RNDN);
1837 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1838 struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
1840 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
1842 static inline const result_type& get(const mpl::int_<N>&)
1844 detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
1845 static result_type result;
1846 static bool init = false;
1849 mpfr_const_euler(result.backend().data(), GMP_RNDN);
1854 static inline const result_type get(const mpl::int_<0>&)
1857 mpfr_const_euler(result.backend().data(), GMP_RNDN);
1861 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1862 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
1864 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
1866 static inline const result_type& get(const mpl::int_<N>&)
1868 detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
1869 static result_type result;
1870 static bool init = false;
1873 mpfr_const_catalan(result.backend().data(), GMP_RNDN);
1878 static inline const result_type get(const mpl::int_<0>&)
1881 mpfr_const_catalan(result.backend().data(), GMP_RNDN);
1886 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1887 struct constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
1889 typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
1891 static inline const result_type& get(const mpl::int_<N>&)
1893 detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
1894 static result_type result;
1895 static bool has_init = false;
1898 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
1903 static inline const result_type get(const mpl::int_<0>&)
1906 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
1910 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1911 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
1913 typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
1915 static inline const result_type& get(const mpl::int_<N>&)
1917 detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
1918 static result_type result;
1919 static bool init = false;
1922 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
1927 static inline const result_type get(const mpl::int_<0>&)
1930 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
1934 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1935 struct constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
1937 typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
1939 static inline const result_type& get(const mpl::int_<N>&)
1941 detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
1942 static result_type result;
1943 static bool init = false;
1946 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
1951 static inline const result_type get(const mpl::int_<0>&)
1954 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
1958 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1959 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
1961 typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
1963 static inline const result_type& get(const mpl::int_<N>&)
1965 detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
1966 static result_type result;
1967 static bool init = false;
1970 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
1975 static inline const result_type get(const mpl::int_<0>&)
1978 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
1983 }} // namespace constants::detail
1987 namespace multiprecision {
1989 // Overloaded special functions which call native mpfr routines:
1991 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1992 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1994 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
1996 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1997 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2000 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2001 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2003 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2005 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2006 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2009 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2010 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2012 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2014 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2015 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2018 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2019 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2021 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2023 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2024 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2027 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2028 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2030 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2032 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2033 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
2036 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2037 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2039 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2041 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2042 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
2045 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2046 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2048 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2050 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2051 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
2054 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2055 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2057 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2059 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2060 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2063 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2064 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2066 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2068 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2069 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2072 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2073 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2075 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2077 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2078 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
2082 } // namespace multiprecision
2086 // Overloaded special functions which call native mpfr routines:
2088 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2089 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2091 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2093 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2094 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2095 if (mpfr_inf_p(result.backend().data()))
2096 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("asinh<%1%>(%1%)", 0, Policy());
2097 if (mpfr_nan_p(result.backend().data()))
2098 return policies::raise_evaluation_error("asinh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2101 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2102 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2104 return asinh(arg, policies::policy<>());
2107 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2108 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2110 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2112 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2113 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2114 if (mpfr_inf_p(result.backend().data()))
2115 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("acosh<%1%>(%1%)", 0, Policy());
2116 if (mpfr_nan_p(result.backend().data()))
2117 return policies::raise_evaluation_error("acosh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2120 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2121 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2123 return acosh(arg, policies::policy<>());
2126 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2127 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& )
2129 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2131 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2132 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2133 if (mpfr_inf_p(result.backend().data()))
2134 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("atanh<%1%>(%1%)", 0, Policy());
2135 if (mpfr_nan_p(result.backend().data()))
2136 return policies::raise_evaluation_error("atanh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2139 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2140 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2142 return atanh(arg, policies::policy<>());
2145 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2146 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2148 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2150 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2151 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2152 if (mpfr_inf_p(result.backend().data()))
2153 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("cbrt<%1%>(%1%)", 0, Policy());
2154 if (mpfr_nan_p(result.backend().data()))
2155 return policies::raise_evaluation_error("cbrt<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2158 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2159 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2161 return cbrt(arg, policies::policy<>());
2164 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2165 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2167 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2169 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2170 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
2171 if (mpfr_inf_p(result.backend().data()))
2172 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erf<%1%>(%1%)", 0, pol);
2173 if (mpfr_nan_p(result.backend().data()))
2174 return policies::raise_evaluation_error("erf<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2177 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2178 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2180 return erf(arg, policies::policy<>());
2183 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2184 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2186 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2188 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2189 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
2190 if (mpfr_inf_p(result.backend().data()))
2191 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erfc<%1%>(%1%)", 0, pol);
2192 if (mpfr_nan_p(result.backend().data()))
2193 return policies::raise_evaluation_error("erfc<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2196 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2197 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2199 return erfc(arg, policies::policy<>());
2202 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2203 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2205 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2207 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2208 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
2209 if (mpfr_inf_p(result.backend().data()))
2210 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("expm1<%1%>(%1%)", 0, pol);
2211 if (mpfr_nan_p(result.backend().data()))
2212 return policies::raise_evaluation_error("expm1<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2215 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2216 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2218 return expm1(arg, policies::policy<>());
2221 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2222 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> arg, int* sign, const Policy& pol)
2224 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2225 (void)precision_guard; // warning suppression
2227 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2230 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2236 if (floor(arg) == arg)
2237 return policies::raise_pole_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >(
2238 "lgamma<%1%>", "Evaluation of lgamma at a negative integer %1%.", arg, pol);
2240 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> t = detail::sinpx(arg);
2246 result = log(boost::math::constants::pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >()) - lgamma(arg, 0, pol) - log(t);
2249 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> phase = 1 - arg;
2250 phase = floor(phase) / 2;
2251 if (floor(phase) == phase)
2257 if (mpfr_inf_p(result.backend().data()))
2258 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("lgamma<%1%>(%1%)", 0, pol);
2259 if (mpfr_nan_p(result.backend().data()))
2260 return policies::raise_evaluation_error("lgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2263 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2264 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, int* sign)
2266 return lgamma(arg, sign, policies::policy<>());
2268 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2269 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2271 return lgamma(arg, 0, pol);
2273 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2274 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2276 return lgamma(arg, 0, policies::policy<>());
2279 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2280 inline typename boost::enable_if_c<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2282 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2284 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2285 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2286 if (mpfr_inf_p(result.backend().data()))
2287 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("tgamma<%1%>(%1%)", 0, pol);
2288 if (mpfr_nan_p(result.backend().data()))
2289 return policies::raise_evaluation_error("tgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2292 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2293 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2295 return tgamma(arg, policies::policy<>());
2298 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2299 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2301 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2303 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2304 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
2305 if (mpfr_inf_p(result.backend().data()))
2306 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("log1p<%1%>(%1%)", 0, pol);
2307 if (mpfr_nan_p(result.backend().data()))
2308 return policies::raise_evaluation_error("log1p<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2311 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2312 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2314 return log1p(arg, policies::policy<>());
2319 } // namespace boost
2324 // numeric_limits [partial] specializations for the types declared in this header:
2326 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2327 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2329 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> number_type;
2332 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2333 static number_type(min)()
2335 initializer.do_nothing();
2336 static std::pair<bool, number_type> value;
2341 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin(), GMP_RNDN);
2343 return value.second;
2345 static number_type(max)()
2347 initializer.do_nothing();
2348 static std::pair<bool, number_type> value;
2353 mpfr_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax(), GMP_RNDN);
2355 return value.second;
2357 BOOST_STATIC_CONSTEXPR number_type lowest()
2361 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
2362 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
2363 // Is this really correct???
2364 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 3;
2365 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2366 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2367 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2368 BOOST_STATIC_CONSTEXPR int radix = 2;
2369 static number_type epsilon()
2371 initializer.do_nothing();
2372 static std::pair<bool, number_type> value;
2377 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
2379 return value.second;
2381 // What value should this be????
2382 static number_type round_error()
2384 // returns epsilon/2
2385 initializer.do_nothing();
2386 static std::pair<bool, number_type> value;
2391 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), 1, GMP_RNDN);
2393 return value.second;
2395 BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
2396 BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
2397 BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
2398 BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
2399 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
2400 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
2401 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2402 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2403 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2404 static number_type infinity()
2406 // returns epsilon/2
2407 initializer.do_nothing();
2408 static std::pair<bool, number_type> value;
2413 mpfr_set_inf(value.second.backend().data(), 1);
2415 return value.second;
2417 static number_type quiet_NaN()
2419 // returns epsilon/2
2420 initializer.do_nothing();
2421 static std::pair<bool, number_type> value;
2426 mpfr_set_nan(value.second.backend().data());
2428 return value.second;
2430 BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
2432 return number_type(0);
2434 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
2435 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2436 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
2437 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2438 BOOST_STATIC_CONSTEXPR bool traps = true;
2439 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2440 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
2443 struct data_initializer
2447 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::epsilon();
2448 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::round_error();
2449 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::min)();
2450 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::max)();
2451 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::infinity();
2452 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::quiet_NaN();
2454 void do_nothing() const {}
2456 static const data_initializer initializer;
2459 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2460 const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::initializer;
2462 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2464 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2465 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
2466 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2467 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
2468 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2469 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
2470 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2471 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
2472 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2473 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
2474 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2475 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
2476 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2477 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
2478 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2479 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
2480 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2481 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
2482 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2483 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
2484 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2485 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
2486 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2487 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
2488 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2489 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
2490 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2491 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
2492 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2493 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
2494 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2495 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
2496 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2497 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
2498 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2499 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
2500 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2501 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
2502 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2503 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
2504 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2505 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
2506 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2507 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
2511 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2512 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
2514 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> number_type;
2517 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
2518 static number_type(min)()
2520 number_type value(0.5);
2521 mpfr_div_2exp(value.backend().data(), value.backend().data(), -mpfr_get_emin(), GMP_RNDN);
2524 static number_type(max)()
2526 number_type value(0.5);
2527 mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
2530 static number_type lowest()
2534 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
2535 BOOST_STATIC_CONSTEXPR int digits10 = INT_MAX;
2536 BOOST_STATIC_CONSTEXPR int max_digits10 = INT_MAX;
2537 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2538 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2539 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2540 BOOST_STATIC_CONSTEXPR int radix = 2;
2541 static number_type epsilon()
2543 number_type value(1);
2544 mpfr_div_2exp(value.backend().data(), value.backend().data(), boost::multiprecision::detail::digits10_2_2(number_type::default_precision()) - 1, GMP_RNDN);
2547 static number_type round_error()
2549 return epsilon() / 2;
2551 BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
2552 BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
2553 BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
2554 BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
2555 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
2556 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
2557 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2558 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2559 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2560 static number_type infinity()
2563 mpfr_set_inf(value.backend().data(), 1);
2566 static number_type quiet_NaN()
2569 mpfr_set_nan(value.backend().data());
2572 static number_type signaling_NaN() { return number_type(0); }
2573 static number_type denorm_min() { return number_type(0); }
2574 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2575 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
2576 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2577 BOOST_STATIC_CONSTEXPR bool traps = false;
2578 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2579 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
2582 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2584 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2585 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
2586 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2587 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
2588 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2589 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
2590 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2591 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
2592 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2593 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
2594 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2595 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
2596 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2597 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
2598 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2599 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
2600 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2601 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
2602 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2603 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
2604 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2605 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
2606 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2607 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
2608 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2609 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
2610 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2611 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
2612 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2613 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
2614 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2615 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
2616 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2617 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
2618 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2619 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
2620 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2621 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
2622 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2623 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
2624 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2625 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
2626 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2627 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;