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_MPFI_HPP
7 #define BOOST_MATH_BN_MPFI_HPP
9 #include <boost/multiprecision/number.hpp>
10 #include <boost/math/special_functions/fpclassify.hpp>
11 #include <boost/cstdint.hpp>
12 #include <boost/multiprecision/detail/big_lanczos.hpp>
13 #include <boost/multiprecision/detail/digits.hpp>
14 #include <boost/multiprecision/mpfr.hpp>
15 #include <boost/multiprecision/logged_adaptor.hpp>
16 #include <boost/math/constants/constants.hpp>
17 #include <boost/functional/hash_fwd.hpp>
22 #ifndef BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION
23 # define BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION 20
27 namespace multiprecision{
30 template <unsigned digits10>
31 struct mpfi_float_backend;
33 } // namespace backends
35 template <unsigned digits10>
36 struct number_category<backends::mpfi_float_backend<digits10> > : public mpl::int_<number_kind_floating_point>{};
38 struct interval_error : public std::runtime_error
40 interval_error(const std::string& s) : std::runtime_error(s) {}
47 inline int mpfi_sgn(mpfi_srcptr p)
51 if(mpfi_is_strictly_pos(p))
53 if(mpfi_is_strictly_neg(p))
55 BOOST_THROW_EXCEPTION(interval_error("Sign of interval is ambiguous."));
58 template <unsigned digits10>
59 struct mpfi_float_imp;
61 template <unsigned digits10>
64 #ifdef BOOST_HAS_LONG_LONG
65 typedef mpl::list<long, boost::long_long_type> signed_types;
66 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
68 typedef mpl::list<long> signed_types;
69 typedef mpl::list<unsigned long> unsigned_types;
71 typedef mpl::list<double, long double> float_types;
72 typedef long exponent_type;
76 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
77 mpfi_set_ui(m_data, 0u);
79 mpfi_float_imp(unsigned prec)
81 mpfi_init2(m_data, prec);
82 mpfi_set_ui(m_data, 0u);
85 mpfi_float_imp(const mpfi_float_imp& o)
87 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
88 if(o.m_data[0].left._mpfr_d)
89 mpfi_set(m_data, o.m_data);
91 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
92 mpfi_float_imp(mpfi_float_imp&& o) BOOST_NOEXCEPT
94 m_data[0] = o.m_data[0];
95 o.m_data[0].left._mpfr_d = 0;
98 mpfi_float_imp& operator = (const mpfi_float_imp& o)
100 if(m_data[0].left._mpfr_d == 0)
101 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
102 if(o.m_data[0].left._mpfr_d)
103 mpfi_set(m_data, o.m_data);
106 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
107 mpfi_float_imp& operator = (mpfi_float_imp&& o) BOOST_NOEXCEPT
109 mpfi_swap(m_data, o.m_data);
113 #ifdef BOOST_HAS_LONG_LONG
114 #ifdef _MPFR_H_HAVE_INTMAX_T
115 mpfi_float_imp& operator = (boost::ulong_long_type i)
117 if(m_data[0].left._mpfr_d == 0)
118 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
119 mpfr_set_uj(left_data(), i, GMP_RNDD);
120 mpfr_set_uj(right_data(), i, GMP_RNDU);
123 mpfi_float_imp& operator = (boost::long_long_type i)
125 if(m_data[0].left._mpfr_d == 0)
126 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
127 mpfr_set_sj(left_data(), i, GMP_RNDD);
128 mpfr_set_sj(right_data(), i, GMP_RNDU);
132 mpfi_float_imp& operator = (boost::ulong_long_type i)
134 if(m_data[0].left._mpfr_d == 0)
135 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
136 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1u);
139 mpfi_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10))));
140 mpfi_set_ui(m_data, 0);
143 mpfi_set_ui(t, static_cast<unsigned long>(i & mask));
145 mpfi_mul_2exp(t, t, shift);
146 mpfi_add(m_data, m_data, t);
147 shift += std::numeric_limits<unsigned long>::digits;
148 i >>= std::numeric_limits<unsigned long>::digits;
153 mpfi_float_imp& operator = (boost::long_long_type i)
155 if(m_data[0].left._mpfr_d == 0)
156 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
158 *this = boost::multiprecision::detail::unsigned_abs(i);
160 mpfi_neg(m_data, m_data);
165 mpfi_float_imp& operator = (unsigned long i)
167 if(m_data[0].left._mpfr_d == 0)
168 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
169 mpfi_set_ui(m_data, i);
172 mpfi_float_imp& operator = (long i)
174 if(m_data[0].left._mpfr_d == 0)
175 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
176 mpfi_set_si(m_data, i);
179 mpfi_float_imp& operator = (double d)
181 if(m_data[0].left._mpfr_d == 0)
182 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
183 mpfi_set_d(m_data, d);
186 mpfi_float_imp& operator = (long double a)
188 if(m_data[0].left._mpfr_d == 0)
189 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
190 mpfr_set_ld(left_data(), a, GMP_RNDD);
191 mpfr_set_ld(right_data(), a, GMP_RNDU);
194 mpfi_float_imp& operator = (const char* s)
196 using default_ops::eval_fpclassify;
198 if(m_data[0].left._mpfr_d == 0)
199 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
203 mpfr_float_backend<digits10> a, b;
206 while(*p && (*p != ',') && (*p != '}'))
208 part.assign(s + 1, p);
211 if(*p && (*p != '}'))
214 while(*p && (*p != ',') && (*p != '}'))
216 part.assign(s + 1, p);
222 if(eval_fpclassify(a) == (int)FP_NAN)
224 mpfi_set_fr(this->data(), a.data());
226 else if(eval_fpclassify(b) == (int)FP_NAN)
228 mpfi_set_fr(this->data(), b.data());
234 BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end)."));
236 mpfi_interv_fr(m_data, a.data(), b.data());
239 else if(mpfi_set_str(m_data, s, 10) != 0)
241 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
245 void swap(mpfi_float_imp& o) BOOST_NOEXCEPT
247 mpfi_swap(m_data, o.m_data);
249 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
251 BOOST_ASSERT(m_data[0].left._mpfr_d);
253 mpfr_float_backend<digits10> a, b;
255 mpfi_get_left(a.data(), m_data);
256 mpfi_get_right(b.data(), m_data);
258 if(a.compare(b) == 0)
259 return a.str(digits, f);
261 return "{" + a.str(digits, f) + "," + b.str(digits, f) + "}";
263 ~mpfi_float_imp() BOOST_NOEXCEPT
265 if(m_data[0].left._mpfr_d)
268 void negate() BOOST_NOEXCEPT
270 BOOST_ASSERT(m_data[0].left._mpfr_d);
271 mpfi_neg(m_data, m_data);
273 int compare(const mpfi_float_imp& o)const BOOST_NOEXCEPT
275 BOOST_ASSERT(m_data[0].left._mpfr_d && o.m_data[0].left._mpfr_d);
276 if(mpfr_cmp(right_data(), o.left_data()) < 0)
278 if(mpfr_cmp(left_data(), o.right_data()) > 0)
280 if((mpfr_cmp(left_data(), o.left_data()) == 0) && (mpfr_cmp(right_data(), o.right_data()) == 0))
282 BOOST_THROW_EXCEPTION(interval_error("Ambiguous comparison between two values."));
286 int compare(V v)const BOOST_NOEXCEPT
292 mpfi_t& data() BOOST_NOEXCEPT
294 BOOST_ASSERT(m_data[0].left._mpfr_d);
297 const mpfi_t& data()const BOOST_NOEXCEPT
299 BOOST_ASSERT(m_data[0].left._mpfr_d);
302 mpfr_ptr left_data() BOOST_NOEXCEPT
304 BOOST_ASSERT(m_data[0].left._mpfr_d);
305 return &(m_data[0].left);
307 mpfr_srcptr left_data()const BOOST_NOEXCEPT
309 BOOST_ASSERT(m_data[0].left._mpfr_d);
310 return &(m_data[0].left);
312 mpfr_ptr right_data() BOOST_NOEXCEPT
314 BOOST_ASSERT(m_data[0].left._mpfr_d);
315 return &(m_data[0].right);
317 mpfr_srcptr right_data()const BOOST_NOEXCEPT
319 BOOST_ASSERT(m_data[0].left._mpfr_d);
320 return &(m_data[0].right);
324 static unsigned& get_default_precision() BOOST_NOEXCEPT
326 static unsigned val = BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION;
331 } // namespace detail
333 template <unsigned digits10>
334 struct mpfi_float_backend : public detail::mpfi_float_imp<digits10>
336 mpfi_float_backend() : detail::mpfi_float_imp<digits10>() {}
337 mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<digits10>(o) {}
338 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
339 mpfi_float_backend(mpfi_float_backend&& o) : detail::mpfi_float_imp<digits10>(static_cast<detail::mpfi_float_imp<digits10>&&>(o)) {}
341 template <unsigned D>
342 mpfi_float_backend(const mpfi_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
343 : detail::mpfi_float_imp<digits10>()
345 mpfi_set(this->m_data, val.data());
347 template <unsigned D>
348 explicit mpfi_float_backend(const mpfi_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
349 : detail::mpfi_float_imp<digits10>()
351 mpfi_set(this->m_data, val.data());
353 mpfi_float_backend(const mpfi_t val)
354 : detail::mpfi_float_imp<digits10>()
356 mpfi_set(this->m_data, val);
358 mpfi_float_backend& operator=(const mpfi_float_backend& o)
360 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10> const&>(o);
363 template <unsigned D>
364 mpfi_float_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
365 : detail::mpfi_float_imp<digits10>()
367 mpfi_set_fr(this->m_data, val.data());
369 template <unsigned D>
370 mpfi_float_backend& operator=(const mpfr_float_backend<D>& val)
372 mpfi_set_fr(this->m_data, val.data());
375 template <unsigned D>
376 explicit mpfi_float_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
377 : detail::mpfi_float_imp<digits10>()
379 mpfi_set_fr(this->m_data, val.data());
381 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
382 mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
384 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10>&&>(o);
389 mpfi_float_backend& operator=(const V& v)
391 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = v;
394 mpfi_float_backend& operator=(const mpfi_t val)
396 mpfi_set(this->m_data, val);
399 // We don't change our precision here, this is a fixed precision type:
400 template <unsigned D>
401 mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
403 mpfi_set(this->m_data, val.data());
409 struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0>
411 mpfi_float_backend() : detail::mpfi_float_imp<0>() {}
412 mpfi_float_backend(const mpfi_t val)
413 : detail::mpfi_float_imp<0>(mpfi_get_prec(val))
415 mpfi_set(this->m_data, val);
417 mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<0>(o) {}
418 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
419 mpfi_float_backend(mpfi_float_backend&& o) BOOST_NOEXCEPT : detail::mpfi_float_imp<0>(static_cast<detail::mpfi_float_imp<0>&&>(o)) {}
421 mpfi_float_backend(const mpfi_float_backend& o, unsigned digits10)
422 : detail::mpfi_float_imp<0>(digits10)
426 template <unsigned D>
427 mpfi_float_backend(const mpfi_float_backend<D>& val)
428 : detail::mpfi_float_imp<0>(mpfi_get_prec(val.data()))
430 mpfi_set(this->m_data, val.data());
432 mpfi_float_backend& operator=(const mpfi_float_backend& o)
434 mpfi_set_prec(this->m_data, mpfi_get_prec(o.data()));
435 mpfi_set(this->m_data, o.data());
438 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
439 mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
441 *static_cast<detail::mpfi_float_imp<0>*>(this) = static_cast<detail::mpfi_float_imp<0> &&>(o);
446 mpfi_float_backend& operator=(const V& v)
448 *static_cast<detail::mpfi_float_imp<0>*>(this) = v;
451 mpfi_float_backend& operator=(const mpfi_t val)
453 mpfi_set_prec(this->m_data, mpfi_get_prec(val));
454 mpfi_set(this->m_data, val);
457 template <unsigned D>
458 mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
460 mpfi_set_prec(this->m_data, mpfi_get_prec(val.data()));
461 mpfi_set(this->m_data, val.data());
464 static unsigned default_precision() BOOST_NOEXCEPT
466 return get_default_precision();
468 static void default_precision(unsigned v) BOOST_NOEXCEPT
470 get_default_precision() = v;
472 unsigned precision()const BOOST_NOEXCEPT
474 return multiprecision::detail::digits2_2_10(mpfi_get_prec(this->m_data));
476 void precision(unsigned digits10) BOOST_NOEXCEPT
478 mpfi_set_prec(this->m_data, multiprecision::detail::digits2_2_10((digits10)));
482 template <unsigned digits10, class T>
483 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
485 return a.compare(b) == 0;
487 template <unsigned digits10, class T>
488 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
490 return a.compare(b) < 0;
492 template <unsigned digits10, class T>
493 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
495 return a.compare(b) > 0;
498 template <unsigned D1, unsigned D2>
499 inline void eval_add(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
501 mpfi_add(result.data(), result.data(), o.data());
503 template <unsigned D1, unsigned D2>
504 inline void eval_subtract(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
506 mpfi_sub(result.data(), result.data(), o.data());
508 template <unsigned D1, unsigned D2>
509 inline void eval_multiply(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
511 if((void*)&result == (void*)&o)
512 mpfi_sqr(result.data(), o.data());
514 mpfi_mul(result.data(), result.data(), o.data());
516 template <unsigned D1, unsigned D2>
517 inline void eval_divide(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
519 mpfi_div(result.data(), result.data(), o.data());
521 template <unsigned digits10>
522 inline void eval_add(mpfi_float_backend<digits10>& result, unsigned long i)
524 mpfi_add_ui(result.data(), result.data(), i);
526 template <unsigned digits10>
527 inline void eval_subtract(mpfi_float_backend<digits10>& result, unsigned long i)
529 mpfi_sub_ui(result.data(), result.data(), i);
531 template <unsigned digits10>
532 inline void eval_multiply(mpfi_float_backend<digits10>& result, unsigned long i)
534 mpfi_mul_ui(result.data(), result.data(), i);
536 template <unsigned digits10>
537 inline void eval_divide(mpfi_float_backend<digits10>& result, unsigned long i)
539 mpfi_div_ui(result.data(), result.data(), i);
541 template <unsigned digits10>
542 inline void eval_add(mpfi_float_backend<digits10>& result, long i)
545 mpfi_add_ui(result.data(), result.data(), i);
547 mpfi_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
549 template <unsigned digits10>
550 inline void eval_subtract(mpfi_float_backend<digits10>& result, long i)
553 mpfi_sub_ui(result.data(), result.data(), i);
555 mpfi_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
557 template <unsigned digits10>
558 inline void eval_multiply(mpfi_float_backend<digits10>& result, long i)
560 mpfi_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
562 mpfi_neg(result.data(), result.data());
564 template <unsigned digits10>
565 inline void eval_divide(mpfi_float_backend<digits10>& result, long i)
567 mpfi_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
569 mpfi_neg(result.data(), result.data());
572 // Specialised 3 arg versions of the basic operators:
574 template <unsigned D1, unsigned D2, unsigned D3>
575 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
577 mpfi_add(a.data(), x.data(), y.data());
579 template <unsigned D1, unsigned D2>
580 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
582 mpfi_add_ui(a.data(), x.data(), y);
584 template <unsigned D1, unsigned D2>
585 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
588 mpfi_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
590 mpfi_add_ui(a.data(), x.data(), y);
592 template <unsigned D1, unsigned D2>
593 inline void eval_add(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
595 mpfi_add_ui(a.data(), y.data(), x);
597 template <unsigned D1, unsigned D2>
598 inline void eval_add(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
602 mpfi_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
603 mpfi_neg(a.data(), a.data());
606 mpfi_add_ui(a.data(), y.data(), x);
608 template <unsigned D1, unsigned D2, unsigned D3>
609 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
611 mpfi_sub(a.data(), x.data(), y.data());
613 template <unsigned D1, unsigned D2>
614 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
616 mpfi_sub_ui(a.data(), x.data(), y);
618 template <unsigned D1, unsigned D2>
619 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
622 mpfi_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
624 mpfi_sub_ui(a.data(), x.data(), y);
626 template <unsigned D1, unsigned D2>
627 inline void eval_subtract(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
629 mpfi_ui_sub(a.data(), x, y.data());
631 template <unsigned D1, unsigned D2>
632 inline void eval_subtract(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
636 mpfi_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
637 mpfi_neg(a.data(), a.data());
640 mpfi_ui_sub(a.data(), x, y.data());
643 template <unsigned D1, unsigned D2, unsigned D3>
644 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
646 if((void*)&x == (void*)&y)
647 mpfi_sqr(a.data(), x.data());
649 mpfi_mul(a.data(), x.data(), y.data());
651 template <unsigned D1, unsigned D2>
652 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
654 mpfi_mul_ui(a.data(), x.data(), y);
656 template <unsigned D1, unsigned D2>
657 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
661 mpfi_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
665 mpfi_mul_ui(a.data(), x.data(), y);
667 template <unsigned D1, unsigned D2>
668 inline void eval_multiply(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
670 mpfi_mul_ui(a.data(), y.data(), x);
672 template <unsigned D1, unsigned D2>
673 inline void eval_multiply(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
677 mpfi_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
678 mpfi_neg(a.data(), a.data());
681 mpfi_mul_ui(a.data(), y.data(), x);
684 template <unsigned D1, unsigned D2, unsigned D3>
685 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
687 mpfi_div(a.data(), x.data(), y.data());
689 template <unsigned D1, unsigned D2>
690 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
692 mpfi_div_ui(a.data(), x.data(), y);
694 template <unsigned D1, unsigned D2>
695 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
699 mpfi_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
703 mpfi_div_ui(a.data(), x.data(), y);
705 template <unsigned D1, unsigned D2>
706 inline void eval_divide(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
708 mpfi_ui_div(a.data(), x, y.data());
710 template <unsigned D1, unsigned D2>
711 inline void eval_divide(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
715 mpfi_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
716 mpfi_neg(a.data(), a.data());
719 mpfi_ui_div(a.data(), x, y.data());
722 template <unsigned digits10>
723 inline bool eval_is_zero(const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
725 return 0 != mpfi_is_zero(val.data());
727 template <unsigned digits10>
728 inline int eval_get_sign(const mpfi_float_backend<digits10>& val)
730 return detail::mpfi_sgn(val.data());
733 template <unsigned digits10>
734 inline void eval_convert_to(unsigned long* result, const mpfi_float_backend<digits10>& val)
736 mpfr_float_backend<digits10> t;
737 mpfi_mid(t.data(), val.data());
738 eval_convert_to(result, t);
740 template <unsigned digits10>
741 inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& val)
743 mpfr_float_backend<digits10> t;
744 mpfi_mid(t.data(), val.data());
745 eval_convert_to(result, t);
747 #ifdef _MPFR_H_HAVE_INTMAX_T
748 template <unsigned digits10>
749 inline void eval_convert_to(boost::ulong_long_type* result, const mpfi_float_backend<digits10>& val)
751 mpfr_float_backend<digits10> t;
752 mpfi_mid(t.data(), val.data());
753 eval_convert_to(result, t);
755 template <unsigned digits10>
756 inline void eval_convert_to(boost::long_long_type* result, const mpfi_float_backend<digits10>& val)
758 mpfr_float_backend<digits10> t;
759 mpfi_mid(t.data(), val.data());
760 eval_convert_to(result, t);
763 template <unsigned digits10>
764 inline void eval_convert_to(double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
766 *result = mpfi_get_d(val.data());
768 template <unsigned digits10>
769 inline void eval_convert_to(long double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
771 mpfr_float_backend<digits10> t;
772 mpfi_mid(t.data(), val.data());
773 eval_convert_to(result, t);
776 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
777 inline void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
779 using default_ops::eval_fpclassify;
780 if(eval_fpclassify(a) == (int)FP_NAN)
782 mpfi_set_fr(result.data(), a.data());
784 else if(eval_fpclassify(b) == (int)FP_NAN)
786 mpfi_set_fr(result.data(), b.data());
792 BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end)."));
794 mpfi_interv_fr(result.data(), a.data(), b.data());
798 template <unsigned Digits10, class V>
799 inline typename enable_if_c<is_convertible<V, number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> >::value >::type
800 assign_components(mpfi_float_backend<Digits10>& result, const V& a, const V& b)
802 number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> x(a), y(b);
803 assign_components(result, x.backend(), y.backend());
807 // Native non-member operations:
809 template <unsigned Digits10>
810 inline void eval_sqrt(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
812 mpfi_sqrt(result.data(), val.data());
815 template <unsigned Digits10>
816 inline void eval_abs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
818 mpfi_abs(result.data(), val.data());
821 template <unsigned Digits10>
822 inline void eval_fabs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
824 mpfi_abs(result.data(), val.data());
826 template <unsigned Digits10>
827 inline void eval_ceil(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
829 mpfr_float_backend<Digits10> a, b;
830 mpfr_set(a.data(), val.left_data(), GMP_RNDN);
831 mpfr_set(b.data(), val.right_data(), GMP_RNDN);
834 if(a.compare(b) != 0)
836 BOOST_THROW_EXCEPTION(interval_error("Attempt to take the ceil of a value that straddles an integer boundary."));
838 mpfi_set_fr(result.data(), a.data());
840 template <unsigned Digits10>
841 inline void eval_floor(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
843 mpfr_float_backend<Digits10> a, b;
844 mpfr_set(a.data(), val.left_data(), GMP_RNDN);
845 mpfr_set(b.data(), val.right_data(), GMP_RNDN);
848 if(a.compare(b) != 0)
850 BOOST_THROW_EXCEPTION(interval_error("Attempt to take the floor of a value that straddles an integer boundary."));
852 mpfi_set_fr(result.data(), a.data());
854 template <unsigned Digits10>
855 inline void eval_ldexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long e)
858 mpfi_mul_2exp(result.data(), val.data(), e);
860 mpfi_div_2exp(result.data(), val.data(), -e);
864 template <unsigned Digits10>
865 inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, int* e)
867 mpfr_float_backend<Digits10> t, rt;
868 mpfi_mid(t.data(), val.data());
869 eval_frexp(rt, t, e);
870 eval_ldexp(result, val, -*e);
872 template <unsigned Digits10>
873 inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long* e)
875 mpfr_float_backend<Digits10> t, rt;
876 mpfi_mid(t.data(), val.data());
877 eval_frexp(rt, t, e);
878 eval_ldexp(result, val, -*e);
881 template <unsigned Digits10>
882 inline int eval_fpclassify(const mpfi_float_backend<Digits10>& val) BOOST_NOEXCEPT
884 return mpfi_inf_p(val.data()) ? FP_INFINITE : mpfi_nan_p(val.data()) ? FP_NAN : mpfi_is_zero(val.data()) ? FP_ZERO : FP_NORMAL;
887 template <unsigned Digits10>
888 inline void eval_pow(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& b, const mpfi_float_backend<Digits10>& e)
890 typedef typename boost::multiprecision::detail::canonical<unsigned, mpfi_float_backend<Digits10> >::type ui_type;
891 using default_ops::eval_get_sign;
892 int s = eval_get_sign(b);
895 if(eval_get_sign(e) == 0)
907 if(eval_get_sign(e) < 0)
909 mpfi_float_backend<Digits10> t1, t2;
914 eval_divide(result, t1, t2);
917 typename boost::multiprecision::detail::canonical<boost::uintmax_t, mpfi_float_backend<Digits10> >::type an;
918 #ifndef BOOST_NO_EXCEPTIONS
922 using default_ops::eval_convert_to;
923 eval_convert_to(&an, e);
924 if(e.compare(an) == 0)
926 mpfi_float_backend<Digits10> pb(b);
928 eval_pow(result, pb, e);
933 #ifndef BOOST_NO_EXCEPTIONS
935 catch(const std::exception&)
937 // conversion failed, just fall through, value is not an integer.
940 result = std::numeric_limits<number<mpfi_float_backend<Digits10>, et_on> >::quiet_NaN().backend();
943 mpfi_log(result.data(), b.data());
944 mpfi_mul(result.data(), result.data(), e.data());
945 mpfi_exp(result.data(), result.data());
948 template <unsigned Digits10>
949 inline void eval_exp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
951 mpfi_exp(result.data(), arg.data());
954 template <unsigned Digits10>
955 inline void eval_exp2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
957 mpfi_exp2(result.data(), arg.data());
960 template <unsigned Digits10>
961 inline void eval_log(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
963 mpfi_log(result.data(), arg.data());
966 template <unsigned Digits10>
967 inline void eval_log10(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
969 mpfi_log10(result.data(), arg.data());
972 template <unsigned Digits10>
973 inline void eval_sin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
975 mpfi_sin(result.data(), arg.data());
978 template <unsigned Digits10>
979 inline void eval_cos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
981 mpfi_cos(result.data(), arg.data());
984 template <unsigned Digits10>
985 inline void eval_tan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
987 mpfi_tan(result.data(), arg.data());
990 template <unsigned Digits10>
991 inline void eval_asin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
993 mpfi_asin(result.data(), arg.data());
996 template <unsigned Digits10>
997 inline void eval_acos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
999 mpfi_acos(result.data(), arg.data());
1002 template <unsigned Digits10>
1003 inline void eval_atan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1005 mpfi_atan(result.data(), arg.data());
1008 template <unsigned Digits10>
1009 inline void eval_atan2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg1, const mpfi_float_backend<Digits10>& arg2)
1011 mpfi_atan2(result.data(), arg1.data(), arg2.data());
1014 template <unsigned Digits10>
1015 inline void eval_sinh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1017 mpfi_sinh(result.data(), arg.data());
1020 template <unsigned Digits10>
1021 inline void eval_cosh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1023 mpfi_cosh(result.data(), arg.data());
1026 template <unsigned Digits10>
1027 inline void eval_tanh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1029 mpfi_tanh(result.data(), arg.data());
1032 template <unsigned Digits10>
1033 inline void eval_log2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1035 mpfi_log2(result.data(), arg.data());
1038 template <unsigned Digits10>
1039 inline std::size_t hash_value(const mpfi_float_backend<Digits10>& val)
1041 std::size_t result = 0;
1042 std::size_t len = val.left_data()[0]._mpfr_prec / mp_bits_per_limb;
1043 if(val.left_data()[0]._mpfr_prec % mp_bits_per_limb)
1045 for(int i = 0; i < len; ++i)
1046 boost::hash_combine(result, val.left_data()[0]._mpfr_d[i]);
1047 boost::hash_combine(result, val.left_data()[0]._mpfr_exp);
1048 boost::hash_combine(result, val.left_data()[0]._mpfr_sign);
1050 len = val.right_data()[0]._mpfr_prec / mp_bits_per_limb;
1051 if(val.right_data()[0]._mpfr_prec % mp_bits_per_limb)
1053 for(int i = 0; i < len; ++i)
1054 boost::hash_combine(result, val.right_data()[0]._mpfr_d[i]);
1055 boost::hash_combine(result, val.right_data()[0]._mpfr_exp);
1056 boost::hash_combine(result, val.right_data()[0]._mpfr_sign);
1060 template <class To, unsigned D>
1061 void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const mpl::int_<number_kind_integer>& to_type, const mpl::int_<number_kind_floating_point>& from_type)
1063 using boost::multiprecision::detail::generic_interconvert;
1064 mpfr_float_backend<D> t;
1065 mpfi_mid(t.data(), from.data());
1066 generic_interconvert(to, t, to_type, from_type);
1069 template <class To, unsigned D>
1070 void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const mpl::int_<number_kind_rational>& to_type, const mpl::int_<number_kind_floating_point>& from_type)
1072 using boost::multiprecision::detail::generic_interconvert;
1073 mpfr_float_backend<D> t;
1074 mpfi_mid(t.data(), from.data());
1075 generic_interconvert(to, t, to_type, from_type);
1078 template <class To, unsigned D>
1079 void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const mpl::int_<number_kind_floating_point>& to_type, const mpl::int_<number_kind_floating_point>& from_type)
1081 using boost::multiprecision::detail::generic_interconvert;
1082 mpfr_float_backend<D> t;
1083 mpfi_mid(t.data(), from.data());
1084 generic_interconvert(to, t, to_type, from_type);
1087 } // namespace backends
1089 #ifdef BOOST_NO_SFINAE_EXPR
1093 template<unsigned D1, unsigned D2>
1094 struct is_explicitly_convertible<backends::mpfi_float_backend<D1>, backends::mpfi_float_backend<D2> > : public mpl::true_ {};
1100 struct number_category<detail::canonical<mpfi_t, backends::mpfi_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
1101 template <unsigned Digits10>
1102 struct is_interval_number<backends::mpfi_float_backend<Digits10> > : public mpl::true_ {};
1104 using boost::multiprecision::backends::mpfi_float_backend;
1106 typedef number<mpfi_float_backend<50> > mpfi_float_50;
1107 typedef number<mpfi_float_backend<100> > mpfi_float_100;
1108 typedef number<mpfi_float_backend<500> > mpfi_float_500;
1109 typedef number<mpfi_float_backend<1000> > mpfi_float_1000;
1110 typedef number<mpfi_float_backend<0> > mpfi_float;
1113 // Special interval specific functions:
1115 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1116 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> lower(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
1118 number<mpfr_float_backend<Digits10> > result;
1119 mpfr_set(result.backend().data(), val.backend().left_data(), GMP_RNDN);
1123 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1124 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> upper(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
1126 number<mpfr_float_backend<Digits10> > result;
1127 mpfr_set(result.backend().data(), val.backend().right_data(), GMP_RNDN);
1131 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1132 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> median(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
1134 number<mpfr_float_backend<Digits10> > result;
1135 mpfi_mid(result.backend().data(), val.backend().data());
1139 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1140 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> width(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
1142 number<mpfr_float_backend<Digits10> > result;
1143 mpfi_diam_abs(result.backend().data(), val.backend().data());
1147 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1148 inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> intersect(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1150 number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1151 mpfi_intersect(result.backend().data(), a.backend().data(), b.backend().data());
1155 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1156 inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> hull(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1158 number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1159 mpfi_union(result.backend().data(), a.backend().data(), b.backend().data());
1163 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1164 inline bool overlap(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1166 return (lower(a) <= lower(b) && lower(b) <= upper(a)) ||
1167 (lower(b) <= lower(a) && lower(a) <= upper(b));
1170 template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
1171 inline bool in(const number<mpfr_float_backend<Digits10>, ExpressionTemplates1>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates2>& b)
1173 return mpfi_is_inside_fr(a.backend().data(), b.backend().data()) != 0;
1176 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1177 inline bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
1179 return mpfi_has_zero(a.backend().data()) != 0;
1182 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1183 inline bool subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1185 return mpfi_is_inside(a.backend().data(), b.backend().data()) != 0;
1188 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1189 inline bool proper_subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1191 return mpfi_is_strictly_inside(a.backend().data(), b.backend().data()) != 0;
1194 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1195 inline bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
1197 return mpfi_is_empty(a.backend().data()) != 0;
1200 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1201 inline bool singleton(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
1203 return mpfr_cmp(a.backend().left_data(), a.backend().right_data()) == 0;
1206 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1207 struct component_type<number<mpfi_float_backend<Digits10>, ExpressionTemplates> >
1209 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1213 // Overloaded special functions which call native mpfr routines:
1215 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1216 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg)
1218 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1219 mpfi_asinh(result.backend().data(), arg.backend().data());
1220 return BOOST_MP_MOVE(result);
1222 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1223 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg)
1225 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1226 mpfi_acosh(result.backend().data(), arg.backend().data());
1227 return BOOST_MP_MOVE(result);
1229 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1230 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg)
1232 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1233 mpfi_atanh(result.backend().data(), arg.backend().data());
1234 return BOOST_MP_MOVE(result);
1236 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1237 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg)
1239 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1240 mpfi_cbrt(result.backend().data(), arg.backend().data());
1241 return BOOST_MP_MOVE(result);
1243 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1244 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg)
1246 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1247 mpfi_expm1(result.backend().data(), arg.backend().data());
1248 return BOOST_MP_MOVE(result);
1250 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1251 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>& arg)
1253 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1254 mpfi_log1p(result.backend().data(), arg.backend().data());
1255 return BOOST_MP_MOVE(result);
1259 } // namespace multiprecision
1266 inline int digits<boost::multiprecision::mpfi_float>()
1267 #ifdef BOOST_MATH_NOEXCEPT
1271 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfi_float::default_precision());
1274 inline int digits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
1275 #ifdef BOOST_MATH_NOEXCEPT
1279 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfi_float::default_precision());
1283 inline boost::multiprecision::mpfi_float
1284 max_value<boost::multiprecision::mpfi_float>()
1286 boost::multiprecision::mpfi_float result(0.5);
1287 mpfi_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax());
1288 //BOOST_ASSERT(mpfi_number_p(result.backend().data()));
1293 inline boost::multiprecision::mpfi_float
1294 min_value<boost::multiprecision::mpfi_float>()
1296 boost::multiprecision::mpfi_float result(0.5);
1297 mpfi_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin());
1298 //BOOST_ASSERT(mpfi_number_p(result.backend().data()));
1303 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off>
1304 max_value<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
1306 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> result(0.5);
1307 mpfi_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax());
1308 //BOOST_ASSERT(mpfi_number_p(result.backend().data()));
1313 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off>
1314 min_value<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
1316 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> result(0.5);
1317 mpfi_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin());
1318 //BOOST_ASSERT(mpfi_number_p(result.backend().data()));
1322 // mpfi gets used with logged_adaptor fairly often, so specialize for that use case as well:
1323 typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_on> logged_type1;
1324 typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_off> logged_type2;
1327 inline int digits<logged_type1>()
1328 #ifdef BOOST_MATH_NOEXCEPT
1332 return multiprecision::detail::digits10_2_2(logged_type1::default_precision());
1335 inline int digits<logged_type2 >()
1336 #ifdef BOOST_MATH_NOEXCEPT
1340 return multiprecision::detail::digits10_2_2(logged_type1::default_precision());
1345 max_value<logged_type1>()
1347 logged_type1 result(0.5);
1348 mpfi_mul_2exp(result.backend().value().data(), result.backend().value().data(), mpfr_get_emax());
1349 //BOOST_ASSERT(mpfi_number_p(result.backend().data()));
1355 min_value<logged_type1>()
1357 logged_type1 result(0.5);
1358 mpfi_div_2exp(result.backend().value().data(), result.backend().value().data(), -mpfr_get_emin());
1359 //BOOST_ASSERT(mpfi_number_p(result.backend().data()));
1365 max_value<logged_type2 >()
1367 logged_type2 result(0.5);
1368 mpfi_mul_2exp(result.backend().value().data(), result.backend().value().data(), mpfr_get_emax());
1369 //BOOST_ASSERT(mpfi_number_p(result.backend().data()));
1375 min_value<logged_type2 >()
1377 logged_type2 result(0.5);
1378 mpfi_div_2exp(result.backend().value().data(), result.backend().value().data(), -mpfr_get_emin());
1379 //BOOST_ASSERT(mpfi_number_p(result.backend().data()));
1382 } // namespace tools
1384 namespace constants{ namespace detail{
1386 template <class T> struct constant_pi;
1387 template <class T> struct constant_ln_two;
1388 template <class T> struct constant_euler;
1389 template <class T> struct constant_catalan;
1392 // Initializer: ensure all our constants are initialized prior to the first call of main:
1395 struct mpfi_initializer
1401 boost::math::constants::pi<T>();
1402 boost::math::constants::ln_two<T>();
1403 boost::math::constants::euler<T>();
1404 boost::math::constants::catalan<T>();
1406 void force_instantiate()const{}
1408 static const init initializer;
1409 static void force_instantiate()
1411 initializer.force_instantiate();
1416 const typename mpfi_initializer<T>::init mpfi_initializer<T>::initializer;
1418 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1419 struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
1421 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
1423 static inline result_type const& get(const mpl::int_<N>&)
1425 mpfi_initializer<result_type>::force_instantiate();
1426 static result_type result;
1427 static bool has_init = false;
1431 mpfi_const_pi(result.backend().data());
1435 static inline result_type get(const mpl::int_<0>&)
1438 mpfi_const_pi(result.backend().data());
1442 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1443 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
1445 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
1447 static inline result_type get(const mpl::int_<N>&)
1449 mpfi_initializer<result_type>::force_instantiate();
1450 static result_type result;
1451 static bool has_init = false;
1455 mpfi_const_log2(result.backend().data());
1459 static inline result_type get(const mpl::int_<0>&)
1462 mpfi_const_log2(result.backend().data());
1466 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1467 struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
1469 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
1471 static inline result_type const& get(const mpl::int_<N>&)
1473 mpfi_initializer<result_type>::force_instantiate();
1474 static result_type result;
1475 static bool has_init = false;
1479 mpfi_const_euler(result.backend().data());
1483 static inline result_type get(const mpl::int_<0>&)
1486 mpfi_const_euler(result.backend().data());
1490 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1491 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
1493 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
1495 static inline result_type const& get(const mpl::int_<N>&)
1497 mpfi_initializer<result_type>::force_instantiate();
1498 static result_type result;
1499 static bool has_init = false;
1503 mpfi_const_catalan(result.backend().data());
1507 static inline result_type get(const mpl::int_<0>&)
1510 mpfi_const_catalan(result.backend().data());
1522 // numeric_limits [partial] specializations for the types declared in this header:
1524 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1525 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
1527 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> number_type;
1529 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
1530 static number_type (min)()
1532 initializer.do_nothing();
1533 static std::pair<bool, number_type> value;
1538 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin());
1540 return value.second;
1542 static number_type (max)()
1544 initializer.do_nothing();
1545 static std::pair<bool, number_type> value;
1550 mpfi_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax());
1552 return value.second;
1554 BOOST_STATIC_CONSTEXPR number_type lowest()
1558 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
1559 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
1560 // Is this really correct???
1561 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 3;
1562 BOOST_STATIC_CONSTEXPR bool is_signed = true;
1563 BOOST_STATIC_CONSTEXPR bool is_integer = false;
1564 BOOST_STATIC_CONSTEXPR bool is_exact = false;
1565 BOOST_STATIC_CONSTEXPR int radix = 2;
1566 static number_type epsilon()
1568 initializer.do_nothing();
1569 static std::pair<bool, number_type> value;
1574 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
1576 return value.second;
1578 // What value should this be????
1579 static number_type round_error()
1581 // returns epsilon/2
1582 initializer.do_nothing();
1583 static std::pair<bool, number_type> value;
1588 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), 1);
1590 return value.second;
1592 BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
1593 BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
1594 BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
1595 BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
1596 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
1597 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
1598 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
1599 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
1600 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
1601 static number_type infinity()
1603 initializer.do_nothing();
1604 static std::pair<bool, number_type> value;
1607 boost::multiprecision::mpfr_float_backend<Digits10> t;
1608 mpfr_set_inf(t.data(), 1);
1610 mpfi_set_fr(value.second.backend().data(), t.data());
1612 return value.second;
1614 static number_type quiet_NaN()
1616 initializer.do_nothing();
1617 static std::pair<bool, number_type> value;
1620 boost::multiprecision::mpfr_float_backend<Digits10> t;
1621 mpfr_set_nan(t.data());
1623 mpfi_set_fr(value.second.backend().data(), t.data());
1625 return value.second;
1627 BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
1629 return number_type(0);
1631 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
1632 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
1633 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
1634 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
1635 BOOST_STATIC_CONSTEXPR bool traps = true;
1636 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
1637 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
1640 struct data_initializer
1644 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::epsilon();
1645 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::round_error();
1646 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::min)();
1647 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::max)();
1648 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::infinity();
1649 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::quiet_NaN();
1651 void do_nothing()const{}
1653 static const data_initializer initializer;
1656 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1657 const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::initializer;
1659 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
1661 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1662 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits;
1663 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1664 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits10;
1665 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1666 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_digits10;
1667 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1668 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_signed;
1669 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1670 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_integer;
1671 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1672 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_exact;
1673 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1674 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::radix;
1675 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1676 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent;
1677 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1678 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent10;
1679 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1680 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent;
1681 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1682 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent10;
1683 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1684 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_infinity;
1685 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1686 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
1687 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1688 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
1689 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1690 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm;
1691 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1692 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm_loss;
1693 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1694 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_iec559;
1695 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1696 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_bounded;
1697 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1698 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_modulo;
1699 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1700 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::traps;
1701 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1702 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::tinyness_before;
1703 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1704 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::round_style;
1709 template<boost::multiprecision::expression_template_option ExpressionTemplates>
1710 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >
1712 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> number_type;
1714 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
1715 static number_type (min)() { return number_type(0); }
1716 static number_type (max)() { return number_type(0); }
1717 static number_type lowest() { return number_type(0); }
1718 BOOST_STATIC_CONSTEXPR int digits = 0;
1719 BOOST_STATIC_CONSTEXPR int digits10 = 0;
1720 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
1721 BOOST_STATIC_CONSTEXPR bool is_signed = false;
1722 BOOST_STATIC_CONSTEXPR bool is_integer = false;
1723 BOOST_STATIC_CONSTEXPR bool is_exact = false;
1724 BOOST_STATIC_CONSTEXPR int radix = 0;
1725 static number_type epsilon() { return number_type(0); }
1726 static number_type round_error() { return number_type(0); }
1727 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
1728 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
1729 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
1730 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
1731 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
1732 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
1733 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
1734 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
1735 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
1736 static number_type infinity() { return number_type(0); }
1737 static number_type quiet_NaN() { return number_type(0); }
1738 static number_type signaling_NaN() { return number_type(0); }
1739 static number_type denorm_min() { return number_type(0); }
1740 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
1741 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
1742 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
1743 BOOST_STATIC_CONSTEXPR bool traps = false;
1744 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
1745 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
1748 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
1750 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1751 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits;
1752 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1753 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits10;
1754 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1755 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_digits10;
1756 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1757 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_signed;
1758 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1759 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_integer;
1760 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1761 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_exact;
1762 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1763 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::radix;
1764 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1765 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent;
1766 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1767 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent10;
1768 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1769 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent;
1770 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1771 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent10;
1772 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1773 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_infinity;
1774 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1775 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
1776 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1777 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
1778 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1779 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm;
1780 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1781 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
1782 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1783 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_iec559;
1784 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1785 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_bounded;
1786 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1787 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_modulo;
1788 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1789 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::traps;
1790 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1791 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::tinyness_before;
1792 template <boost::multiprecision::expression_template_option ExpressionTemplates>
1793 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::round_style;