File indexing completed on 2025-01-30 09:48:49
0001
0002
0003
0004
0005
0006 #ifndef BOOST_MP_MPFI_HPP
0007 #define BOOST_MP_MPFI_HPP
0008
0009 #include <algorithm>
0010 #include <cmath>
0011 #include <cstdint>
0012 #include <type_traits>
0013 #include <string>
0014 #include <boost/multiprecision/detail/standalone_config.hpp>
0015 #include <boost/multiprecision/detail/fpclassify.hpp>
0016 #include <boost/multiprecision/number.hpp>
0017 #include <boost/multiprecision/detail/digits.hpp>
0018 #include <boost/multiprecision/detail/precision.hpp>
0019 #include <boost/multiprecision/detail/atomic.hpp>
0020 #include <boost/multiprecision/traits/max_digits10.hpp>
0021 #include <boost/multiprecision/mpfr.hpp>
0022 #include <boost/multiprecision/logged_adaptor.hpp>
0023 #include <boost/multiprecision/detail/hash.hpp>
0024 #include <boost/multiprecision/detail/no_exceptions_support.hpp>
0025 #include <boost/multiprecision/detail/assert.hpp>
0026 #include <mpfi.h>
0027
0028 #ifdef BOOST_MP_MATH_AVAILABLE
0029 #include <boost/math/constants/constants.hpp>
0030 #endif
0031
0032 #ifndef BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION
0033 #define BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION 20
0034 #endif
0035
0036 namespace boost {
0037 namespace multiprecision {
0038
0039 template <unsigned digits10>
0040 struct number_category<backends::mpfi_float_backend<digits10> > : public std::integral_constant<int, number_kind_floating_point>
0041 {};
0042
0043 struct interval_error : public std::runtime_error
0044 {
0045 interval_error(const std::string& s) : std::runtime_error(s) {}
0046 };
0047
0048 namespace detail {
0049 template <>
0050 struct is_variable_precision<backends::mpfi_float_backend<0> > : public std::integral_constant<bool, true>
0051 {};
0052 }
0053
0054
0055 namespace backends {
0056
0057 namespace detail {
0058
0059 inline int mpfi_sgn(mpfi_srcptr p)
0060 {
0061 if (mpfi_is_zero(p))
0062 return 0;
0063 if (mpfi_is_strictly_pos(p))
0064 return 1;
0065 if (mpfi_is_strictly_neg(p))
0066 return -1;
0067 BOOST_MP_THROW_EXCEPTION(interval_error("Sign of interval is ambiguous."));
0068 }
0069
0070 template <unsigned digits10>
0071 struct mpfi_float_imp;
0072
0073 template <unsigned digits10>
0074 struct mpfi_float_imp
0075 {
0076 #ifdef BOOST_HAS_LONG_LONG
0077 using signed_types = std::tuple<long, long long> ;
0078 using unsigned_types = std::tuple<unsigned long, unsigned long long>;
0079 #else
0080 using signed_types = std::tuple<long> ;
0081 using unsigned_types = std::tuple<unsigned long>;
0082 #endif
0083 using float_types = std::tuple<double, long double>;
0084 using exponent_type = long ;
0085
0086 mpfi_float_imp()
0087 {
0088 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0089 mpfi_set_ui(m_data, 0u);
0090 }
0091 mpfi_float_imp(unsigned prec)
0092 {
0093 mpfi_init2(m_data, prec);
0094 mpfi_set_ui(m_data, 0u);
0095 }
0096
0097 mpfi_float_imp(const mpfi_float_imp& o)
0098 {
0099 mpfi_init2(m_data, preserve_source_precision() ? mpfi_get_prec(o.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
0100 if (o.m_data[0].left._mpfr_d)
0101 mpfi_set(m_data, o.m_data);
0102 }
0103 template <unsigned D, mpfr_allocation_type AllocationType>
0104 mpfi_float_imp(const mpfr_float_imp<D, AllocationType>& o)
0105 {
0106 mpfi_init2(m_data, (D == 0 ? preserve_component_precision() : preserve_related_precision()) ? mpfr_get_prec(o.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
0107 if (o.data()[0]._mpfr_d)
0108 mpfi_set_fr(m_data, o.data());
0109 }
0110
0111 mpfi_float_imp(mpfi_float_imp&& o) noexcept
0112 {
0113 mpfr_prec_t binary_default_precision = boost::multiprecision::detail::digits10_2_2(get_default_precision());
0114 if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpfi_get_prec(o.data()) == binary_default_precision))
0115 {
0116 m_data[0] = o.m_data[0];
0117 o.m_data[0].left._mpfr_d = nullptr;
0118 }
0119 else
0120 {
0121
0122 mpfi_init2(m_data, binary_default_precision);
0123 mpfi_set(m_data, o.m_data);
0124 }
0125 }
0126 mpfi_float_imp& operator=(const mpfi_float_imp& o)
0127 {
0128 if (this != &o)
0129 {
0130 if (m_data[0].left._mpfr_d == nullptr)
0131 mpfi_init2(m_data, preserve_source_precision() ? mpfi_get_prec(o.m_data) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
0132 else if (preserve_source_precision() && (mpfi_get_prec(o.data()) != mpfi_get_prec(data())))
0133 {
0134 mpfi_set_prec(m_data, mpfi_get_prec(o.m_data));
0135 }
0136 mpfi_set(m_data, o.m_data);
0137 }
0138 return *this;
0139 }
0140
0141 mpfi_float_imp& operator=(mpfi_float_imp&& o) noexcept
0142 {
0143 if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpfi_get_prec(o.data()) == mpfi_get_prec(data())))
0144 mpfi_swap(m_data, o.m_data);
0145 else
0146 *this = static_cast<const mpfi_float_imp&>(o);
0147 return *this;
0148 }
0149 #ifdef BOOST_HAS_LONG_LONG
0150 #ifdef _MPFR_H_HAVE_INTMAX_T
0151 mpfi_float_imp& operator=(unsigned long long i)
0152 {
0153 if (m_data[0].left._mpfr_d == nullptr)
0154 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0155 mpfr_set_uj(left_data(), i, GMP_RNDD);
0156 mpfr_set_uj(right_data(), i, GMP_RNDU);
0157 return *this;
0158 }
0159 mpfi_float_imp& operator=(long long i)
0160 {
0161 if (m_data[0].left._mpfr_d == nullptr)
0162 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0163 mpfr_set_sj(left_data(), i, GMP_RNDD);
0164 mpfr_set_sj(right_data(), i, GMP_RNDU);
0165 return *this;
0166 }
0167 #else
0168 mpfi_float_imp& operator=(unsigned long long i)
0169 {
0170 if (m_data[0].left._mpfr_d == nullptr)
0171 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0172 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1u);
0173 unsigned shift = 0;
0174 mpfi_t t;
0175 mpfi_init2(t, (std::max)(static_cast<mpfr_prec_t>(std::numeric_limits<unsigned long long>::digits), static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(digits10))));
0176 mpfi_set_ui(m_data, 0);
0177 while (i)
0178 {
0179 mpfi_set_ui(t, static_cast<unsigned long>(i & mask));
0180 if (shift)
0181 mpfi_mul_2exp(t, t, shift);
0182 mpfi_add(m_data, m_data, t);
0183 shift += std::numeric_limits<unsigned long>::digits;
0184 i >>= std::numeric_limits<unsigned long>::digits;
0185 }
0186 mpfi_clear(t);
0187 return *this;
0188 }
0189 mpfi_float_imp& operator=(long long i)
0190 {
0191 if (m_data[0].left._mpfr_d == nullptr)
0192 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0193 bool neg = i < 0;
0194 *this = boost::multiprecision::detail::unsigned_abs(i);
0195 if (neg)
0196 mpfi_neg(m_data, m_data);
0197 return *this;
0198 }
0199 #endif
0200 #endif
0201 #ifdef BOOST_HAS_INT128
0202 mpfi_float_imp& operator=(uint128_type i)
0203 {
0204 if (m_data[0].left._mpfr_d == nullptr)
0205 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0206 constexpr uint128_type mask = ((((static_cast<uint128_type>(1u) << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1u);
0207 unsigned shift = 0;
0208 mpfi_t t;
0209 mpfi_init2(t, (std::max)(static_cast<mpfr_prec_t>(128), static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(digits10))));
0210 mpfi_set_ui(m_data, 0);
0211 while (i)
0212 {
0213 mpfi_set_ui(t, static_cast<unsigned long>(i & mask));
0214 if (shift)
0215 mpfi_mul_2exp(t, t, shift);
0216 mpfi_add(m_data, m_data, t);
0217 shift += std::numeric_limits<unsigned long>::digits;
0218 i >>= std::numeric_limits<unsigned long>::digits;
0219 }
0220 mpfi_clear(t);
0221 return *this;
0222 }
0223 mpfi_float_imp& operator=(int128_type i)
0224 {
0225 if (m_data[0].left._mpfr_d == nullptr)
0226 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0227 bool neg = i < 0;
0228 *this = boost::multiprecision::detail::unsigned_abs(i);
0229 if (neg)
0230 mpfi_neg(m_data, m_data);
0231 return *this;
0232 }
0233 #endif
0234 mpfi_float_imp& operator=(unsigned long i)
0235 {
0236 if (m_data[0].left._mpfr_d == nullptr)
0237 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0238 mpfi_set_ui(m_data, i);
0239 return *this;
0240 }
0241 mpfi_float_imp& operator=(long i)
0242 {
0243 if (m_data[0].left._mpfr_d == nullptr)
0244 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0245 mpfi_set_si(m_data, i);
0246 return *this;
0247 }
0248 mpfi_float_imp& operator=(double d)
0249 {
0250 if (m_data[0].left._mpfr_d == nullptr)
0251 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0252 mpfi_set_d(m_data, d);
0253 return *this;
0254 }
0255 mpfi_float_imp& operator=(long double a)
0256 {
0257 if (m_data[0].left._mpfr_d == nullptr)
0258 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0259 mpfr_set_ld(left_data(), a, GMP_RNDD);
0260 mpfr_set_ld(right_data(), a, GMP_RNDU);
0261 return *this;
0262 }
0263 #ifdef BOOST_HAS_FLOAT128
0264 mpfi_float_imp& operator=(float128_type a)
0265 {
0266 BOOST_MP_FLOAT128_USING
0267 if (m_data[0].left._mpfr_d == nullptr)
0268 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0269
0270 if (a == 0)
0271 {
0272 mpfi_set_si(m_data, 0);
0273 return *this;
0274 }
0275
0276 if (a == 1)
0277 {
0278 mpfi_set_si(m_data, 1);
0279 return *this;
0280 }
0281
0282 BOOST_MP_ASSERT(!BOOST_MP_ISINF(a));
0283 BOOST_MP_ASSERT(!BOOST_MP_ISNAN(a));
0284
0285 int e;
0286 float128_type f, term;
0287 mpfi_set_ui(m_data, 0u);
0288
0289 f = frexp(a, &e);
0290
0291 constexpr const int shift = std::numeric_limits<int>::digits - 1;
0292
0293 while (f)
0294 {
0295
0296 f = ldexp(f, shift);
0297 term = floor(f);
0298 e -= shift;
0299 mpfi_mul_2exp(m_data, m_data, shift);
0300 if (term > 0)
0301 mpfi_add_ui(m_data, m_data, static_cast<unsigned>(term));
0302 else
0303 mpfi_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
0304 f -= term;
0305 }
0306 if (e > 0)
0307 mpfi_mul_2exp(m_data, m_data, e);
0308 else if (e < 0)
0309 mpfi_div_2exp(m_data, m_data, -e);
0310 return *this;
0311 }
0312 #endif
0313 mpfi_float_imp& operator=(const char* s)
0314 {
0315 using default_ops::eval_fpclassify;
0316
0317 if (m_data[0].left._mpfr_d == nullptr)
0318 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0319
0320 if (s && (*s == '{'))
0321 {
0322 mpfr_float_backend<digits10> a, b;
0323 std::string part;
0324 const char* p = ++s;
0325 while (*p && (*p != ',') && (*p != '}'))
0326 ++p;
0327 part.assign(s, p);
0328 a = part.c_str();
0329 s = p;
0330 if (*p && (*p != '}'))
0331 {
0332 ++p;
0333 while (*p && (*p != ',') && (*p != '}'))
0334 ++p;
0335 part.assign(s + 1, p);
0336 }
0337 else
0338 part.erase();
0339 b = part.c_str();
0340
0341 if (eval_fpclassify(a) == static_cast<int>(FP_NAN))
0342 {
0343 mpfi_set_fr(this->data(), a.data());
0344 }
0345 else if (eval_fpclassify(b) == static_cast<int>(FP_NAN))
0346 {
0347 mpfi_set_fr(this->data(), b.data());
0348 }
0349 else
0350 {
0351 if (a.compare(b) > 0)
0352 {
0353 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end)."));
0354 }
0355 mpfi_interv_fr(m_data, a.data(), b.data());
0356 }
0357 }
0358 else if (mpfi_set_str(m_data, s, 10) != 0)
0359 {
0360 BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
0361 }
0362 return *this;
0363 }
0364 void swap(mpfi_float_imp& o) noexcept
0365 {
0366 mpfi_swap(m_data, o.m_data);
0367 }
0368 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
0369 {
0370 BOOST_MP_ASSERT(m_data[0].left._mpfr_d);
0371
0372 mpfr_float_backend<digits10> a, b;
0373
0374 mpfi_get_left(a.data(), m_data);
0375 mpfi_get_right(b.data(), m_data);
0376
0377 if (a.compare(b) == 0)
0378 return a.str(digits, f);
0379
0380 return "{" + a.str(digits, f) + "," + b.str(digits, f) + "}";
0381 }
0382 ~mpfi_float_imp() noexcept
0383 {
0384 if (m_data[0].left._mpfr_d)
0385 mpfi_clear(m_data);
0386 }
0387 void negate() noexcept
0388 {
0389 BOOST_MP_ASSERT(m_data[0].left._mpfr_d);
0390 mpfi_neg(m_data, m_data);
0391 }
0392 int compare(const mpfi_float_imp& o) const noexcept
0393 {
0394 BOOST_MP_ASSERT(m_data[0].left._mpfr_d && o.m_data[0].left._mpfr_d);
0395 if (mpfr_cmp(right_data(), o.left_data()) < 0)
0396 return -1;
0397 if (mpfr_cmp(left_data(), o.right_data()) > 0)
0398 return 1;
0399 if ((mpfr_cmp(left_data(), o.left_data()) == 0) && (mpfr_cmp(right_data(), o.right_data()) == 0))
0400 return 0;
0401 BOOST_MP_THROW_EXCEPTION(interval_error("Ambiguous comparison between two values."));
0402 return 0;
0403 }
0404 template <class V>
0405 int compare(V v) const noexcept
0406 {
0407 mpfi_float_imp d;
0408 d = v;
0409 return compare(d);
0410 }
0411 mpfi_t& data() noexcept
0412 {
0413 BOOST_MP_ASSERT(m_data[0].left._mpfr_d);
0414 return m_data;
0415 }
0416 const mpfi_t& data() const noexcept
0417 {
0418 BOOST_MP_ASSERT(m_data[0].left._mpfr_d);
0419 return m_data;
0420 }
0421 mpfr_ptr left_data() noexcept
0422 {
0423 BOOST_MP_ASSERT(m_data[0].left._mpfr_d);
0424 return &(m_data[0].left);
0425 }
0426 mpfr_srcptr left_data() const noexcept
0427 {
0428 BOOST_MP_ASSERT(m_data[0].left._mpfr_d);
0429 return &(m_data[0].left);
0430 }
0431 mpfr_ptr right_data() noexcept
0432 {
0433 BOOST_MP_ASSERT(m_data[0].left._mpfr_d);
0434 return &(m_data[0].right);
0435 }
0436 mpfr_srcptr right_data() const noexcept
0437 {
0438 BOOST_MP_ASSERT(m_data[0].left._mpfr_d);
0439 return &(m_data[0].right);
0440 }
0441
0442 protected:
0443 mpfi_t m_data;
0444 static boost::multiprecision::detail::precision_type& get_global_default_precision() noexcept
0445 {
0446 static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION);
0447 return val;
0448 }
0449 static unsigned& get_default_precision() noexcept
0450 {
0451 static BOOST_MP_THREAD_LOCAL unsigned val(get_global_default_precision());
0452 return val;
0453 }
0454 #ifndef BOOST_MT_NO_ATOMIC_INT
0455 static std::atomic<variable_precision_options>& get_global_default_options() noexcept
0456 #else
0457 static variable_precision_options& get_global_default_options() noexcept
0458 #endif
0459 {
0460 #ifndef BOOST_MT_NO_ATOMIC_INT
0461 static std::atomic<variable_precision_options> val{variable_precision_options::preserve_related_precision};
0462 #else
0463 static variable_precision_optionss val{variable_precision_options::preserve_related_precision};
0464 #endif
0465 return val;
0466 }
0467 static variable_precision_options& get_default_options() noexcept
0468 {
0469 static BOOST_MP_THREAD_LOCAL variable_precision_options val(get_global_default_options());
0470 return val;
0471 }
0472 static bool preserve_source_precision() noexcept
0473 {
0474 return get_default_options() >= variable_precision_options::preserve_source_precision;
0475 }
0476 static bool preserve_component_precision() noexcept
0477 {
0478 return get_default_options() >= variable_precision_options::preserve_component_precision;
0479 }
0480 static bool preserve_related_precision() noexcept
0481 {
0482 return get_default_options() >= variable_precision_options::preserve_related_precision;
0483 }
0484 static bool preserve_all_precision() noexcept
0485 {
0486 return get_default_options() >= variable_precision_options::preserve_all_precision;
0487 }
0488 };
0489
0490 }
0491
0492 template <unsigned digits10>
0493 struct mpfi_float_backend : public detail::mpfi_float_imp<digits10>
0494 {
0495 mpfi_float_backend() : detail::mpfi_float_imp<digits10>() {}
0496 mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<digits10>(o) {}
0497
0498 mpfi_float_backend(mpfi_float_backend&& o) : detail::mpfi_float_imp<digits10>(static_cast<detail::mpfi_float_imp<digits10>&&>(o))
0499 {}
0500 template <unsigned D>
0501 mpfi_float_backend(const mpfi_float_backend<D>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
0502 : detail::mpfi_float_imp<digits10>()
0503 {
0504 mpfi_set(this->m_data, val.data());
0505 }
0506 template <unsigned D, mpfr_allocation_type AllocationType>
0507 mpfi_float_backend(const mpfr_float_backend<D, AllocationType>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
0508 : detail::mpfi_float_imp<digits10>(val) {}
0509
0510 template <unsigned D>
0511 explicit mpfi_float_backend(const mpfi_float_backend<D>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
0512 : detail::mpfi_float_imp<digits10>()
0513 {
0514 mpfi_set(this->m_data, val.data());
0515 }
0516 mpfi_float_backend(const mpfi_t val)
0517 : detail::mpfi_float_imp<digits10>()
0518 {
0519 mpfi_set(this->m_data, val);
0520 }
0521 mpfi_float_backend& operator=(const mpfi_float_backend& o)
0522 {
0523 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10> const&>(o);
0524 return *this;
0525 }
0526 template <unsigned D>
0527 mpfi_float_backend(const mpfr_float_backend<D>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
0528 : detail::mpfi_float_imp<digits10>()
0529 {
0530 mpfi_set_fr(this->m_data, val.data());
0531 }
0532 template <unsigned D>
0533 mpfi_float_backend& operator=(const mpfr_float_backend<D>& val)
0534 {
0535 mpfi_set_fr(this->m_data, val.data());
0536 return *this;
0537 }
0538 template <unsigned D>
0539 explicit mpfi_float_backend(const mpfr_float_backend<D>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
0540 : detail::mpfi_float_imp<digits10>()
0541 {
0542 mpfi_set_fr(this->m_data, val.data());
0543 }
0544
0545 mpfi_float_backend& operator=(mpfi_float_backend&& o) noexcept
0546 {
0547 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10>&&>(o);
0548 return *this;
0549 }
0550 template <class V>
0551 typename std::enable_if<std::is_assignable<detail::mpfi_float_imp<digits10>, V>::value, mpfi_float_backend&>::type operator=(const V& v)
0552 {
0553 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = v;
0554 return *this;
0555 }
0556 mpfi_float_backend& operator=(const mpfi_t val)
0557 {
0558 mpfi_set(this->m_data, val);
0559 return *this;
0560 }
0561
0562 template <unsigned D>
0563 mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
0564 {
0565 mpfi_set(this->m_data, val.data());
0566 return *this;
0567 }
0568 };
0569
0570 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
0571 void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b);
0572
0573 template <unsigned Digits10, class V>
0574 typename std::enable_if<std::is_constructible<number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on>, V>::value || std::is_convertible<V, const char*>::value>::type
0575 assign_components(mpfi_float_backend<Digits10>& result, const V& a, const V& b);
0576
0577 template <>
0578 struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0>
0579 {
0580 mpfi_float_backend() : detail::mpfi_float_imp<0>() {}
0581 mpfi_float_backend(const mpfi_t val)
0582 : detail::mpfi_float_imp<0>(mpfi_get_prec(val))
0583 {
0584 mpfi_set(this->m_data, val);
0585 }
0586 mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<0>(o) {}
0587
0588 template <unsigned D, mpfr_allocation_type AllocationType>
0589 mpfi_float_backend(const mpfr_float_backend<D, AllocationType>& val)
0590 : detail::mpfi_float_imp<0>(val) {}
0591
0592
0593 mpfi_float_backend(mpfi_float_backend&& o) noexcept : detail::mpfi_float_imp<0>(static_cast<detail::mpfi_float_imp<0>&&>(o))
0594 {}
0595 mpfi_float_backend(const mpfi_float_backend& o, unsigned digits10)
0596 : detail::mpfi_float_imp<0>(multiprecision::detail::digits10_2_2(digits10))
0597 {
0598 mpfi_set(this->m_data, o.data());
0599 }
0600 template <class V>
0601 mpfi_float_backend(const V& a, const V& b, unsigned digits10)
0602 : detail::mpfi_float_imp<0>(multiprecision::detail::digits10_2_2(digits10))
0603 {
0604 boost::multiprecision::detail::scoped_target_precision<mpfi_float_backend<0> > opts;
0605 assign_components(*this, a, b);
0606 }
0607
0608 template <unsigned D>
0609 mpfi_float_backend(const mpfi_float_backend<D>& val)
0610 : detail::mpfi_float_imp<0>(mpfi_get_prec(val.data()))
0611 {
0612 mpfi_set(this->m_data, val.data());
0613 }
0614 mpfi_float_backend& operator=(const mpfi_float_backend& o) = default;
0615
0616 mpfi_float_backend& operator=(mpfi_float_backend&& o) noexcept = default;
0617
0618 template <class V>
0619 mpfi_float_backend& operator=(const V& v)
0620 {
0621 constexpr unsigned d10 = std::is_floating_point<V>::value ?
0622 std::numeric_limits<V>::digits10 :
0623 std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 :
0624 1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits);
0625
0626 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
0627 {
0628 BOOST_IF_CONSTEXPR(std::is_floating_point<V>::value)
0629 {
0630 if (std::numeric_limits<V>::digits > mpfi_get_prec(this->data()))
0631 mpfi_set_prec(this->data(), std::numeric_limits<V>::digits);
0632 }
0633 else
0634 {
0635 if (precision() < d10)
0636 this->precision(d10);
0637 }
0638 }
0639
0640 *static_cast<detail::mpfi_float_imp<0>*>(this) = v;
0641 return *this;
0642 }
0643 mpfi_float_backend& operator=(const mpfi_t val)
0644 {
0645 mpfi_set_prec(this->m_data, mpfi_get_prec(val));
0646 mpfi_set(this->m_data, val);
0647 return *this;
0648 }
0649 template <unsigned D>
0650 mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
0651 {
0652 mpfi_set_prec(this->m_data, mpfi_get_prec(val.data()));
0653 mpfi_set(this->m_data, val.data());
0654 return *this;
0655 }
0656 static unsigned thread_default_precision() noexcept
0657 {
0658 return get_default_precision();
0659 }
0660 static void thread_default_precision(unsigned v) noexcept
0661 {
0662 get_default_precision() = v;
0663 }
0664 static unsigned default_precision() noexcept
0665 {
0666 return get_global_default_precision();
0667 }
0668 static void default_precision(unsigned v) noexcept
0669 {
0670 get_global_default_precision() = v;
0671 }
0672 unsigned precision() const noexcept
0673 {
0674 return multiprecision::detail::digits2_2_10(mpfi_get_prec(this->m_data));
0675 }
0676 void precision(unsigned digits10) noexcept
0677 {
0678 mpfi_float_backend t(*this, digits10);
0679 this->swap(t);
0680 }
0681
0682
0683
0684 static variable_precision_options default_variable_precision_options() noexcept
0685 {
0686 return get_global_default_options();
0687 }
0688 static variable_precision_options thread_default_variable_precision_options() noexcept
0689 {
0690 return get_default_options();
0691 }
0692 static void default_variable_precision_options(variable_precision_options opts)
0693 {
0694 get_global_default_options() = opts;
0695 }
0696 static void thread_default_variable_precision_options(variable_precision_options opts)
0697 {
0698 get_default_options() = opts;
0699 }
0700 };
0701
0702 template <unsigned digits10, class T>
0703 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_eq(const mpfi_float_backend<digits10>& a, const T& b) noexcept
0704 {
0705 return a.compare(b) == 0;
0706 }
0707 template <unsigned digits10, class T>
0708 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_lt(const mpfi_float_backend<digits10>& a, const T& b) noexcept
0709 {
0710 return a.compare(b) < 0;
0711 }
0712 template <unsigned digits10, class T>
0713 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_gt(const mpfi_float_backend<digits10>& a, const T& b) noexcept
0714 {
0715 return a.compare(b) > 0;
0716 }
0717
0718 template <unsigned D1, unsigned D2>
0719 inline void eval_add(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
0720 {
0721 mpfi_add(result.data(), result.data(), o.data());
0722 }
0723 template <unsigned D1, unsigned D2>
0724 inline void eval_subtract(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
0725 {
0726 mpfi_sub(result.data(), result.data(), o.data());
0727 }
0728 template <unsigned D1, unsigned D2>
0729 inline void eval_multiply(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
0730 {
0731 if ((void*)&result == (void*)&o)
0732 mpfi_sqr(result.data(), o.data());
0733 else
0734 mpfi_mul(result.data(), result.data(), o.data());
0735 }
0736 template <unsigned D1, unsigned D2>
0737 inline void eval_divide(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
0738 {
0739 mpfi_div(result.data(), result.data(), o.data());
0740 }
0741 template <unsigned digits10>
0742 inline void eval_add(mpfi_float_backend<digits10>& result, unsigned long i)
0743 {
0744 mpfi_add_ui(result.data(), result.data(), i);
0745 }
0746 template <unsigned digits10>
0747 inline void eval_subtract(mpfi_float_backend<digits10>& result, unsigned long i)
0748 {
0749 mpfi_sub_ui(result.data(), result.data(), i);
0750 }
0751 template <unsigned digits10>
0752 inline void eval_multiply(mpfi_float_backend<digits10>& result, unsigned long i)
0753 {
0754 mpfi_mul_ui(result.data(), result.data(), i);
0755 }
0756 template <unsigned digits10>
0757 inline void eval_divide(mpfi_float_backend<digits10>& result, unsigned long i)
0758 {
0759 mpfi_div_ui(result.data(), result.data(), i);
0760 }
0761 template <unsigned digits10>
0762 inline void eval_add(mpfi_float_backend<digits10>& result, long i)
0763 {
0764 if (i > 0)
0765 mpfi_add_ui(result.data(), result.data(), i);
0766 else
0767 mpfi_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
0768 }
0769 template <unsigned digits10>
0770 inline void eval_subtract(mpfi_float_backend<digits10>& result, long i)
0771 {
0772 if (i > 0)
0773 mpfi_sub_ui(result.data(), result.data(), i);
0774 else
0775 mpfi_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
0776 }
0777 template <unsigned digits10>
0778 inline void eval_multiply(mpfi_float_backend<digits10>& result, long i)
0779 {
0780 mpfi_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
0781 if (i < 0)
0782 mpfi_neg(result.data(), result.data());
0783 }
0784 template <unsigned digits10>
0785 inline void eval_divide(mpfi_float_backend<digits10>& result, long i)
0786 {
0787 mpfi_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
0788 if (i < 0)
0789 mpfi_neg(result.data(), result.data());
0790 }
0791
0792
0793
0794 template <unsigned D1, unsigned D2, unsigned D3>
0795 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
0796 {
0797 mpfi_add(a.data(), x.data(), y.data());
0798 }
0799 template <unsigned D1, unsigned D2>
0800 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
0801 {
0802 mpfi_add_ui(a.data(), x.data(), y);
0803 }
0804 template <unsigned D1, unsigned D2>
0805 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
0806 {
0807 if (y < 0)
0808 mpfi_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
0809 else
0810 mpfi_add_ui(a.data(), x.data(), y);
0811 }
0812 template <unsigned D1, unsigned D2>
0813 inline void eval_add(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
0814 {
0815 mpfi_add_ui(a.data(), y.data(), x);
0816 }
0817 template <unsigned D1, unsigned D2>
0818 inline void eval_add(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
0819 {
0820 if (x < 0)
0821 {
0822 mpfi_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
0823 mpfi_neg(a.data(), a.data());
0824 }
0825 else
0826 mpfi_add_ui(a.data(), y.data(), x);
0827 }
0828 template <unsigned D1, unsigned D2, unsigned D3>
0829 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
0830 {
0831 mpfi_sub(a.data(), x.data(), y.data());
0832 }
0833 template <unsigned D1, unsigned D2>
0834 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
0835 {
0836 mpfi_sub_ui(a.data(), x.data(), y);
0837 }
0838 template <unsigned D1, unsigned D2>
0839 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
0840 {
0841 if (y < 0)
0842 mpfi_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
0843 else
0844 mpfi_sub_ui(a.data(), x.data(), y);
0845 }
0846 template <unsigned D1, unsigned D2>
0847 inline void eval_subtract(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
0848 {
0849 mpfi_ui_sub(a.data(), x, y.data());
0850 }
0851 template <unsigned D1, unsigned D2>
0852 inline void eval_subtract(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
0853 {
0854 if (x < 0)
0855 {
0856 mpfi_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
0857 mpfi_neg(a.data(), a.data());
0858 }
0859 else
0860 mpfi_ui_sub(a.data(), x, y.data());
0861 }
0862
0863 template <unsigned D1, unsigned D2, unsigned D3>
0864 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
0865 {
0866 if ((void*)&x == (void*)&y)
0867 mpfi_sqr(a.data(), x.data());
0868 else
0869 mpfi_mul(a.data(), x.data(), y.data());
0870 }
0871 template <unsigned D1, unsigned D2>
0872 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
0873 {
0874 mpfi_mul_ui(a.data(), x.data(), y);
0875 }
0876 template <unsigned D1, unsigned D2>
0877 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
0878 {
0879 if (y < 0)
0880 {
0881 mpfi_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
0882 a.negate();
0883 }
0884 else
0885 mpfi_mul_ui(a.data(), x.data(), y);
0886 }
0887 template <unsigned D1, unsigned D2>
0888 inline void eval_multiply(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
0889 {
0890 mpfi_mul_ui(a.data(), y.data(), x);
0891 }
0892 template <unsigned D1, unsigned D2>
0893 inline void eval_multiply(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
0894 {
0895 if (x < 0)
0896 {
0897 mpfi_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
0898 mpfi_neg(a.data(), a.data());
0899 }
0900 else
0901 mpfi_mul_ui(a.data(), y.data(), x);
0902 }
0903
0904 template <unsigned D1, unsigned D2, unsigned D3>
0905 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
0906 {
0907 mpfi_div(a.data(), x.data(), y.data());
0908 }
0909 template <unsigned D1, unsigned D2>
0910 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
0911 {
0912 mpfi_div_ui(a.data(), x.data(), y);
0913 }
0914 template <unsigned D1, unsigned D2>
0915 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
0916 {
0917 if (y < 0)
0918 {
0919 mpfi_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
0920 a.negate();
0921 }
0922 else
0923 mpfi_div_ui(a.data(), x.data(), y);
0924 }
0925 template <unsigned D1, unsigned D2>
0926 inline void eval_divide(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
0927 {
0928 mpfi_ui_div(a.data(), x, y.data());
0929 }
0930 template <unsigned D1, unsigned D2>
0931 inline void eval_divide(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
0932 {
0933 if (x < 0)
0934 {
0935 mpfi_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
0936 mpfi_neg(a.data(), a.data());
0937 }
0938 else
0939 mpfi_ui_div(a.data(), x, y.data());
0940 }
0941
0942 template <unsigned digits10>
0943 inline bool eval_is_zero(const mpfi_float_backend<digits10>& val) noexcept
0944 {
0945 return 0 != mpfi_is_zero(val.data());
0946 }
0947 template <unsigned digits10>
0948 inline int eval_get_sign(const mpfi_float_backend<digits10>& val)
0949 {
0950 return detail::mpfi_sgn(val.data());
0951 }
0952
0953 template <unsigned digits10>
0954 inline void eval_convert_to(unsigned long* result, const mpfi_float_backend<digits10>& val)
0955 {
0956 mpfr_float_backend<digits10> t;
0957 mpfi_mid(t.data(), val.data());
0958 eval_convert_to(result, t);
0959 }
0960 template <unsigned digits10>
0961 inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& val)
0962 {
0963 mpfr_float_backend<digits10> t;
0964 mpfi_mid(t.data(), val.data());
0965 eval_convert_to(result, t);
0966 }
0967 #ifdef _MPFR_H_HAVE_INTMAX_T
0968 template <unsigned digits10>
0969 inline void eval_convert_to(unsigned long long* result, const mpfi_float_backend<digits10>& val)
0970 {
0971 mpfr_float_backend<digits10> t;
0972 mpfi_mid(t.data(), val.data());
0973 eval_convert_to(result, t);
0974 }
0975 template <unsigned digits10>
0976 inline void eval_convert_to(long long* result, const mpfi_float_backend<digits10>& val)
0977 {
0978 mpfr_float_backend<digits10> t;
0979 mpfi_mid(t.data(), val.data());
0980 eval_convert_to(result, t);
0981 }
0982 #endif
0983 #ifdef BOOST_HAS_INT128
0984 template <unsigned digits10>
0985 inline void eval_convert_to(uint128_type* result, const mpfi_float_backend<digits10>& val)
0986 {
0987 mpfr_float_backend<digits10> t;
0988 mpfi_mid(t.data(), val.data());
0989 eval_convert_to(result, t);
0990 }
0991 template <unsigned digits10>
0992 inline void eval_convert_to(int128_type* result, const mpfi_float_backend<digits10>& val)
0993 {
0994 mpfr_float_backend<digits10> t;
0995 mpfi_mid(t.data(), val.data());
0996 eval_convert_to(result, t);
0997 }
0998 #endif
0999 template <unsigned digits10>
1000 inline void eval_convert_to(double* result, const mpfi_float_backend<digits10>& val) noexcept
1001 {
1002 *result = mpfi_get_d(val.data());
1003 }
1004 template <unsigned digits10>
1005 inline void eval_convert_to(long double* result, const mpfi_float_backend<digits10>& val) noexcept
1006 {
1007 mpfr_float_backend<digits10> t;
1008 mpfi_mid(t.data(), val.data());
1009 eval_convert_to(result, t);
1010 }
1011 #ifdef BOOST_HAS_FLOAT128
1012 template <unsigned digits10>
1013 inline void eval_convert_to(float128_type* result, const mpfi_float_backend<digits10>& val)
1014 {
1015 mpfr_float_backend<digits10> t;
1016 mpfi_mid(t.data(), val.data());
1017 eval_convert_to(result, t);
1018 }
1019 #endif
1020 template <mpfr_allocation_type AllocationType>
1021 inline void assign_components_set_precision(mpfi_float_backend<0>& result, const mpfr_float_backend<0, AllocationType>& a, const mpfr_float_backend<0, AllocationType>& b)
1022 {
1023 if (result.thread_default_variable_precision_options() >= variable_precision_options::preserve_component_precision)
1024 {
1025 unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
1026 mpfi_set_prec(result.data(), prec);
1027 }
1028 }
1029 template <unsigned D2, mpfr_allocation_type AllocationType>
1030 inline void assign_components_set_precision(mpfi_float_backend<0>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
1031 {
1032 if (result.thread_default_variable_precision_options() >= variable_precision_options::preserve_related_precision)
1033 {
1034 unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
1035 mpfi_set_prec(result.data(), prec);
1036 }
1037 }
1038 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1039 inline void assign_components_set_precision(mpfi_float_backend<D1>&, const mpfr_float_backend<D2, AllocationType>&, const mpfr_float_backend<D2, AllocationType>&)
1040 {
1041 }
1042
1043
1044 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1045 inline void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
1046 {
1047
1048
1049
1050
1051 assign_components_set_precision(result, a, b);
1052
1053 using default_ops::eval_fpclassify;
1054 if (eval_fpclassify(a) == static_cast<int>(FP_NAN))
1055 {
1056 mpfi_set_fr(result.data(), a.data());
1057 }
1058 else if (eval_fpclassify(b) == static_cast<int>(FP_NAN))
1059 {
1060 mpfi_set_fr(result.data(), b.data());
1061 }
1062 else
1063 {
1064 if (a.compare(b) > 0)
1065 {
1066 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end)."));
1067 }
1068 mpfi_interv_fr(result.data(), a.data(), b.data());
1069 }
1070 }
1071
1072 template <unsigned Digits10, class V>
1073 inline typename std::enable_if<std::is_constructible<number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on>, V>::value || std::is_convertible<V, const char*>::value>::type
1074 assign_components(mpfi_float_backend<Digits10>& result, const V& a, const V& b)
1075 {
1076 number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> x(a), y(b);
1077 assign_components(result, x.backend(), y.backend());
1078 }
1079
1080
1081
1082
1083 template <unsigned Digits10>
1084 inline void eval_sqrt(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
1085 {
1086 mpfi_sqrt(result.data(), val.data());
1087 }
1088
1089 template <unsigned Digits10>
1090 inline void eval_abs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
1091 {
1092 mpfi_abs(result.data(), val.data());
1093 }
1094
1095 template <unsigned Digits10>
1096 inline void eval_fabs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
1097 {
1098 mpfi_abs(result.data(), val.data());
1099 }
1100 template <unsigned Digits10>
1101 inline void eval_ceil(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
1102 {
1103 mpfr_float_backend<Digits10> a, b;
1104 mpfr_set(a.data(), val.left_data(), GMP_RNDN);
1105 mpfr_set(b.data(), val.right_data(), GMP_RNDN);
1106 eval_ceil(a, a);
1107 eval_ceil(b, b);
1108 if (a.compare(b) != 0)
1109 {
1110 BOOST_MP_THROW_EXCEPTION(interval_error("Attempt to take the ceil of a value that straddles an integer boundary."));
1111 }
1112 mpfi_set_fr(result.data(), a.data());
1113 }
1114 template <unsigned Digits10>
1115 inline void eval_floor(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
1116 {
1117 mpfr_float_backend<Digits10> a, b;
1118 mpfr_set(a.data(), val.left_data(), GMP_RNDN);
1119 mpfr_set(b.data(), val.right_data(), GMP_RNDN);
1120 eval_floor(a, a);
1121 eval_floor(b, b);
1122 if (a.compare(b) != 0)
1123 {
1124 BOOST_MP_THROW_EXCEPTION(interval_error("Attempt to take the floor of a value that straddles an integer boundary."));
1125 }
1126 mpfi_set_fr(result.data(), a.data());
1127 }
1128 template <unsigned Digits10>
1129 inline void eval_ldexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long e)
1130 {
1131 if (e > 0)
1132 mpfi_mul_2exp(result.data(), val.data(), e);
1133 else if (e < 0)
1134 mpfi_div_2exp(result.data(), val.data(), -e);
1135 else
1136 result = val;
1137 }
1138 template <unsigned Digits10>
1139 inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, int* e)
1140 {
1141 mpfr_float_backend<Digits10> t, rt;
1142 mpfi_mid(t.data(), val.data());
1143 eval_frexp(rt, t, e);
1144 eval_ldexp(result, val, -*e);
1145 }
1146 template <unsigned Digits10>
1147 inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long* e)
1148 {
1149 mpfr_float_backend<Digits10> t, rt;
1150 mpfi_mid(t.data(), val.data());
1151 eval_frexp(rt, t, e);
1152 eval_ldexp(result, val, -*e);
1153 }
1154
1155 template <unsigned Digits10>
1156 inline int eval_fpclassify(const mpfi_float_backend<Digits10>& val) noexcept
1157 {
1158 return mpfi_inf_p(val.data()) ? FP_INFINITE : mpfi_nan_p(val.data()) ? FP_NAN : mpfi_is_zero(val.data()) ? FP_ZERO : FP_NORMAL;
1159 }
1160
1161 template <unsigned Digits10>
1162 inline void eval_pow(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& b, const mpfi_float_backend<Digits10>& e)
1163 {
1164 using ui_type = typename boost::multiprecision::detail::canonical<unsigned, mpfi_float_backend<Digits10> >::type;
1165 using default_ops::eval_get_sign;
1166 int s = eval_get_sign(b);
1167 if (s == 0)
1168 {
1169 if (eval_get_sign(e) == 0)
1170 {
1171 result = ui_type(1);
1172 }
1173 else
1174 {
1175 result = ui_type(0);
1176 }
1177 return;
1178 }
1179 if (s < 0)
1180 {
1181 if (eval_get_sign(e) < 0)
1182 {
1183 mpfi_float_backend<Digits10> t1, t2;
1184 t1 = e;
1185 t1.negate();
1186 eval_pow(t2, b, t1);
1187 t1 = ui_type(1);
1188 eval_divide(result, t1, t2);
1189 return;
1190 }
1191 typename boost::multiprecision::detail::canonical<std::uintmax_t, mpfi_float_backend<Digits10> >::type an;
1192 #ifndef BOOST_NO_EXCEPTIONS
1193 try
1194 {
1195 #endif
1196 using default_ops::eval_convert_to;
1197 eval_convert_to(&an, e);
1198 if (e.compare(an) == 0)
1199 {
1200 mpfi_float_backend<Digits10> pb(b);
1201 pb.negate();
1202 eval_pow(result, pb, e);
1203 if (an & 1u)
1204 result.negate();
1205 return;
1206 }
1207 #ifndef BOOST_NO_EXCEPTIONS
1208 }
1209 catch (const std::exception&)
1210 {
1211
1212 }
1213 #endif
1214 result = std::numeric_limits<number<mpfi_float_backend<Digits10>, et_on> >::quiet_NaN().backend();
1215 return;
1216 }
1217 mpfi_log(result.data(), b.data());
1218 mpfi_mul(result.data(), result.data(), e.data());
1219 mpfi_exp(result.data(), result.data());
1220 }
1221
1222 template <unsigned Digits10>
1223 inline void eval_exp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1224 {
1225 mpfi_exp(result.data(), arg.data());
1226 }
1227
1228 template <unsigned Digits10>
1229 inline void eval_exp2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1230 {
1231 mpfi_exp2(result.data(), arg.data());
1232 }
1233
1234 template <unsigned Digits10>
1235 inline void eval_log(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1236 {
1237 mpfi_log(result.data(), arg.data());
1238 }
1239
1240 template <unsigned Digits10>
1241 inline void eval_log10(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1242 {
1243 mpfi_log10(result.data(), arg.data());
1244 }
1245
1246 template <unsigned Digits10>
1247 inline void eval_sin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1248 {
1249 mpfi_sin(result.data(), arg.data());
1250 }
1251
1252 template <unsigned Digits10>
1253 inline void eval_cos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1254 {
1255 mpfi_cos(result.data(), arg.data());
1256 }
1257
1258 template <unsigned Digits10>
1259 inline void eval_tan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1260 {
1261 mpfi_tan(result.data(), arg.data());
1262 }
1263
1264 template <unsigned Digits10>
1265 inline void eval_asin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1266 {
1267 mpfi_asin(result.data(), arg.data());
1268 }
1269
1270 template <unsigned Digits10>
1271 inline void eval_acos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1272 {
1273 mpfi_acos(result.data(), arg.data());
1274 }
1275
1276 template <unsigned Digits10>
1277 inline void eval_atan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1278 {
1279 mpfi_atan(result.data(), arg.data());
1280 }
1281
1282 template <unsigned Digits10>
1283 inline void eval_atan2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg1, const mpfi_float_backend<Digits10>& arg2)
1284 {
1285 mpfi_atan2(result.data(), arg1.data(), arg2.data());
1286 }
1287
1288 template <unsigned Digits10>
1289 inline void eval_sinh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1290 {
1291 mpfi_sinh(result.data(), arg.data());
1292 }
1293
1294 template <unsigned Digits10>
1295 inline void eval_cosh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1296 {
1297 mpfi_cosh(result.data(), arg.data());
1298 }
1299
1300 template <unsigned Digits10>
1301 inline void eval_tanh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1302 {
1303 mpfi_tanh(result.data(), arg.data());
1304 }
1305
1306 template <unsigned Digits10>
1307 inline void eval_log2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1308 {
1309 mpfi_log2(result.data(), arg.data());
1310 }
1311
1312 template <unsigned Digits10>
1313 inline std::size_t hash_value(const mpfi_float_backend<Digits10>& val)
1314 {
1315 std::size_t result = 0;
1316 std::size_t len = val.left_data()[0]._mpfr_prec / mp_bits_per_limb;
1317 if (val.left_data()[0]._mpfr_prec % mp_bits_per_limb)
1318 ++len;
1319 for (std::size_t i = 0; i < len; ++i)
1320 boost::multiprecision::detail::hash_combine(result, val.left_data()[0]._mpfr_d[i]);
1321 boost::multiprecision::detail::hash_combine(result, val.left_data()[0]._mpfr_exp, val.left_data()[0]._mpfr_sign);
1322
1323 len = val.right_data()[0]._mpfr_prec / mp_bits_per_limb;
1324 if (val.right_data()[0]._mpfr_prec % mp_bits_per_limb)
1325 ++len;
1326 for (std::size_t i = 0; i < len; ++i)
1327 boost::multiprecision::detail::hash_combine(result, val.right_data()[0]._mpfr_d[i]);
1328 boost::multiprecision::detail::hash_combine(result, val.right_data()[0]._mpfr_exp, val.right_data()[0]._mpfr_sign);
1329 return result;
1330 }
1331
1332 template <class To, unsigned D>
1333 void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const std::integral_constant<int, number_kind_integer>& to_type, const std::integral_constant<int, number_kind_floating_point>& from_type)
1334 {
1335 using boost::multiprecision::detail::generic_interconvert;
1336 boost::multiprecision::detail::scoped_precision_options<number<mpfr_float_backend<D>>> scoped(from);
1337 mpfr_float_backend<D> t;
1338 mpfi_mid(t.data(), from.data());
1339 generic_interconvert(to, t, to_type, from_type);
1340 }
1341
1342 template <class To, unsigned D>
1343 void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const std::integral_constant<int, number_kind_rational>& to_type, const std::integral_constant<int, number_kind_floating_point>& from_type)
1344 {
1345 using boost::multiprecision::detail::generic_interconvert;
1346 boost::multiprecision::detail::scoped_precision_options<number<mpfr_float_backend<D>>> scoped(from);
1347 mpfr_float_backend<D> t;
1348 mpfi_mid(t.data(), from.data());
1349 generic_interconvert(to, t, to_type, from_type);
1350 }
1351
1352 template <class To, unsigned D>
1353 void generic_interconvert(To& to, const mpfi_float_backend<D>& from, const std::integral_constant<int, number_kind_floating_point>& to_type, const std::integral_constant<int, number_kind_floating_point>& from_type)
1354 {
1355 using boost::multiprecision::detail::generic_interconvert;
1356 boost::multiprecision::detail::scoped_precision_options<number<mpfr_float_backend<D>>> scoped(from);
1357 mpfr_float_backend<D> t;
1358 mpfi_mid(t.data(), from.data());
1359 generic_interconvert(to, t, to_type, from_type);
1360 }
1361
1362 }
1363
1364 template <>
1365 struct number_category<detail::canonical<mpfi_t, backends::mpfi_float_backend<0> >::type> : public std::integral_constant<int, number_kind_floating_point>
1366 {};
1367 template <unsigned Digits10>
1368 struct is_interval_number<backends::mpfi_float_backend<Digits10> > : public std::integral_constant<bool, true>
1369 {};
1370
1371
1372
1373
1374 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1375 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> lower(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
1376 {
1377 boost::multiprecision::detail::scoped_precision_options<number<mpfr_float_backend<Digits10>, ExpressionTemplates> > precision_guard(val);
1378 number<mpfr_float_backend<Digits10> > result;
1379 mpfr_set(result.backend().data(), val.backend().left_data(), GMP_RNDN);
1380 return result;
1381 }
1382
1383 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1384 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> upper(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
1385 {
1386 boost::multiprecision::detail::scoped_precision_options<number<mpfr_float_backend<Digits10>, ExpressionTemplates> > precision_guard(val);
1387 number<mpfr_float_backend<Digits10> > result;
1388 mpfr_set(result.backend().data(), val.backend().right_data(), GMP_RNDN);
1389 return result;
1390 }
1391
1392 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1393 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> median(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
1394 {
1395 boost::multiprecision::detail::scoped_precision_options<number<mpfr_float_backend<Digits10>, ExpressionTemplates> > precision_guard(val);
1396 number<mpfr_float_backend<Digits10> > result;
1397 mpfi_mid(result.backend().data(), val.backend().data());
1398 return result;
1399 }
1400
1401 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1402 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> width(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
1403 {
1404 boost::multiprecision::detail::scoped_precision_options<number<mpfr_float_backend<Digits10>, ExpressionTemplates> > precision_guard(val);
1405 number<mpfr_float_backend<Digits10> > result;
1406 mpfi_diam_abs(result.backend().data(), val.backend().data());
1407 return result;
1408 }
1409
1410 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1411 inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> intersect(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1412 {
1413 boost::multiprecision::detail::scoped_default_precision<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > precision_guard(a, b);
1414 number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1415 mpfi_intersect(result.backend().data(), a.backend().data(), b.backend().data());
1416 return result;
1417 }
1418
1419 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1420 inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> hull(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1421 {
1422 boost::multiprecision::detail::scoped_default_precision<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > precision_guard(a, b);
1423 number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1424 mpfi_union(result.backend().data(), a.backend().data(), b.backend().data());
1425 return result;
1426 }
1427
1428 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1429 inline bool overlap(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1430 {
1431 return (lower(a) <= lower(b) && lower(b) <= upper(a)) ||
1432 (lower(b) <= lower(a) && lower(a) <= upper(b));
1433 }
1434
1435 template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
1436 inline bool in(const number<mpfr_float_backend<Digits10>, ExpressionTemplates1>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates2>& b)
1437 {
1438 return mpfi_is_inside_fr(a.backend().data(), b.backend().data()) != 0;
1439 }
1440
1441 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1442 inline bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
1443 {
1444 return mpfi_has_zero(a.backend().data()) != 0;
1445 }
1446
1447 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1448 inline bool subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1449 {
1450 return mpfi_is_inside(a.backend().data(), b.backend().data()) != 0;
1451 }
1452
1453 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1454 inline bool proper_subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
1455 {
1456 return mpfi_is_strictly_inside(a.backend().data(), b.backend().data()) != 0;
1457 }
1458
1459 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1460 inline bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
1461 {
1462 return mpfi_is_empty(a.backend().data()) != 0;
1463 }
1464
1465 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1466 inline bool singleton(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
1467 {
1468 return mpfr_cmp(a.backend().left_data(), a.backend().right_data()) == 0;
1469 }
1470
1471
1472
1473
1474 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1475 inline number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> lower(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& val)
1476 {
1477 boost::multiprecision::detail::scoped_default_precision<number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(val);
1478 number<debug_adaptor<mpfr_float_backend<Digits10> > > result;
1479 mpfr_set(result.backend().value().data(), val.backend().value().left_data(), GMP_RNDN);
1480 return result;
1481 }
1482
1483 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1484 inline number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> upper(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& val)
1485 {
1486 boost::multiprecision::detail::scoped_default_precision<number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(val);
1487 number<debug_adaptor<mpfr_float_backend<Digits10> > > result;
1488 mpfr_set(result.backend().value().data(), val.backend().value().right_data(), GMP_RNDN);
1489 return result;
1490 }
1491
1492 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1493 inline number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> median(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& val)
1494 {
1495 boost::multiprecision::detail::scoped_default_precision<number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(val);
1496 number<debug_adaptor<mpfr_float_backend<Digits10> > > result;
1497 mpfi_mid(result.backend().value().data(), val.backend().value().data());
1498 return result;
1499 }
1500
1501 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1502 inline number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> width(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& val)
1503 {
1504 boost::multiprecision::detail::scoped_default_precision<number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(val);
1505 number<debug_adaptor<mpfr_float_backend<Digits10> > > result;
1506 mpfi_diam_abs(result.backend().value().data(), val.backend().value().data());
1507 return result;
1508 }
1509
1510 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1511 inline number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> intersect(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1512 {
1513 boost::multiprecision::detail::scoped_default_precision<number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(a, b);
1514 number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1515 mpfi_intersect(result.backend().value().data(), a.backend().value().data(), b.backend().value().data());
1516 return result;
1517 }
1518
1519 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1520 inline number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> hull(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1521 {
1522 boost::multiprecision::detail::scoped_default_precision<number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(a, b);
1523 number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1524 mpfi_union(result.backend().value().data(), a.backend().value().data(), b.backend().value().data());
1525 return result;
1526 }
1527
1528 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1529 inline bool overlap(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1530 {
1531 return (lower(a) <= lower(b) && lower(b) <= upper(a)) ||
1532 (lower(b) <= lower(a) && lower(a) <= upper(b));
1533 }
1534
1535 template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
1536 inline bool in(const number<debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates1>& a, const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates2>& b)
1537 {
1538 return mpfi_is_inside_fr(a.backend().value().data(), b.backend().value().data()) != 0;
1539 }
1540
1541 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1542 inline bool zero_in(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a)
1543 {
1544 return mpfi_has_zero(a.backend().value().data()) != 0;
1545 }
1546
1547 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1548 inline bool subset(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1549 {
1550 return mpfi_is_inside(a.backend().value().data(), b.backend().value().data()) != 0;
1551 }
1552
1553 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1554 inline bool proper_subset(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1555 {
1556 return mpfi_is_strictly_inside(a.backend().value().data(), b.backend().value().data()) != 0;
1557 }
1558
1559 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1560 inline bool empty(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a)
1561 {
1562 return mpfi_is_empty(a.backend().value().data()) != 0;
1563 }
1564
1565 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1566 inline bool singleton(const number<debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a)
1567 {
1568 return mpfr_cmp(a.backend().value().left_data(), a.backend().value().right_data()) == 0;
1569 }
1570
1571
1572
1573 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1574 inline number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> lower(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& val)
1575 {
1576 boost::multiprecision::detail::scoped_default_precision<number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(val);
1577 number<logged_adaptor<mpfr_float_backend<Digits10> > > result;
1578 mpfr_set(result.backend().value().data(), val.backend().value().left_data(), GMP_RNDN);
1579 return result;
1580 }
1581
1582 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1583 inline number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> upper(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& val)
1584 {
1585 boost::multiprecision::detail::scoped_default_precision<number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(val);
1586 number<logged_adaptor<mpfr_float_backend<Digits10> > > result;
1587 mpfr_set(result.backend().value().data(), val.backend().value().right_data(), GMP_RNDN);
1588 return result;
1589 }
1590
1591 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1592 inline number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> median(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& val)
1593 {
1594 boost::multiprecision::detail::scoped_default_precision<number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(val);
1595 number<logged_adaptor<mpfr_float_backend<Digits10> > > result;
1596 mpfi_mid(result.backend().value().data(), val.backend().value().data());
1597 return result;
1598 }
1599
1600 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1601 inline number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> width(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& val)
1602 {
1603 boost::multiprecision::detail::scoped_default_precision<number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(val);
1604 number<logged_adaptor<mpfr_float_backend<Digits10> > > result;
1605 mpfi_diam_abs(result.backend().value().data(), val.backend().value().data());
1606 return result;
1607 }
1608
1609 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1610 inline number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> intersect(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1611 {
1612 boost::multiprecision::detail::scoped_default_precision<number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(a, b);
1613 number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1614 mpfi_intersect(result.backend().value().data(), a.backend().value().data(), b.backend().value().data());
1615 return result;
1616 }
1617
1618 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1619 inline number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> hull(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1620 {
1621 boost::multiprecision::detail::scoped_default_precision<number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(a, b);
1622 number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1623 mpfi_union(result.backend().value().data(), a.backend().value().data(), b.backend().value().data());
1624 return result;
1625 }
1626
1627 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1628 inline bool overlap(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1629 {
1630 return (lower(a) <= lower(b) && lower(b) <= upper(a)) ||
1631 (lower(b) <= lower(a) && lower(a) <= upper(b));
1632 }
1633
1634 template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
1635 inline bool in(const number<logged_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates1>& a, const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates2>& b)
1636 {
1637 return mpfi_is_inside_fr(a.backend().value().data(), b.backend().value().data()) != 0;
1638 }
1639
1640 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1641 inline bool zero_in(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a)
1642 {
1643 return mpfi_has_zero(a.backend().value().data()) != 0;
1644 }
1645
1646 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1647 inline bool subset(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1648 {
1649 return mpfi_is_inside(a.backend().value().data(), b.backend().value().data()) != 0;
1650 }
1651
1652 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1653 inline bool proper_subset(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a, const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& b)
1654 {
1655 return mpfi_is_strictly_inside(a.backend().value().data(), b.backend().value().data()) != 0;
1656 }
1657
1658 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1659 inline bool empty(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a)
1660 {
1661 return mpfi_is_empty(a.backend().value().data()) != 0;
1662 }
1663
1664 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1665 inline bool singleton(const number<logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates>& a)
1666 {
1667 return mpfr_cmp(a.backend().value().left_data(), a.backend().value().right_data()) == 0;
1668 }
1669
1670
1671
1672 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1673 struct component_type<number<mpfi_float_backend<Digits10>, ExpressionTemplates> >
1674 {
1675 using type = number<mpfr_float_backend<Digits10>, ExpressionTemplates>;
1676 };
1677
1678
1679
1680
1681 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1682 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)
1683 {
1684 boost::multiprecision::detail::scoped_default_precision<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > precision_guard(arg);
1685
1686 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1687 mpfi_asinh(result.backend().data(), arg.backend().data());
1688 return result;
1689 }
1690 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1691 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)
1692 {
1693 boost::multiprecision::detail::scoped_default_precision<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > precision_guard(arg);
1694
1695 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1696 mpfi_acosh(result.backend().data(), arg.backend().data());
1697 return result;
1698 }
1699 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1700 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)
1701 {
1702 boost::multiprecision::detail::scoped_default_precision<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > precision_guard(arg);
1703
1704 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1705 mpfi_atanh(result.backend().data(), arg.backend().data());
1706 return result;
1707 }
1708 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1709 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)
1710 {
1711 boost::multiprecision::detail::scoped_default_precision<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > precision_guard(arg);
1712
1713 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1714 mpfi_cbrt(result.backend().data(), arg.backend().data());
1715 return result;
1716 }
1717 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1718 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)
1719 {
1720 boost::multiprecision::detail::scoped_default_precision<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > precision_guard(arg);
1721
1722 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1723 mpfi_expm1(result.backend().data(), arg.backend().data());
1724 return result;
1725 }
1726 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1727 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)
1728 {
1729 boost::multiprecision::detail::scoped_default_precision<number<mpfi_float_backend<Digits10>, ExpressionTemplates> > precision_guard(arg);
1730
1731 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result;
1732 mpfi_log1p(result.backend().data(), arg.backend().data());
1733 return result;
1734 }
1735
1736
1737
1738
1739 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1740 inline boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1741 {
1742 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1743
1744 boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1745 mpfi_asinh(result.backend().value().data(), arg.backend().value().data());
1746 return result;
1747 }
1748 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1749 inline boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1750 {
1751 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1752
1753 boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1754 mpfi_acosh(result.backend().value().data(), arg.backend().value().data());
1755 return result;
1756 }
1757 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1758 inline boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1759 {
1760 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1761
1762 boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1763 mpfi_atanh(result.backend().value().data(), arg.backend().value().data());
1764 return result;
1765 }
1766 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1767 inline boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1768 {
1769 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1770
1771 boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1772 mpfi_cbrt(result.backend().value().data(), arg.backend().value().data());
1773 return result;
1774 }
1775 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1776 inline boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1777 {
1778 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1779
1780 boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1781 mpfi_expm1(result.backend().value().data(), arg.backend().value().data());
1782 return result;
1783 }
1784 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1785 inline boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1786 {
1787 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::debug_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1788
1789 boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1790 mpfi_log1p(result.backend().value().data(), arg.backend().value().data());
1791 return result;
1792 }
1793
1794
1795
1796
1797 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1798 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1799 {
1800 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1801
1802 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1803 mpfi_asinh(result.backend().value().data(), arg.backend().value().data());
1804 return result;
1805 }
1806 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1807 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1808 {
1809 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1810
1811 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1812 mpfi_acosh(result.backend().value().data(), arg.backend().value().data());
1813 return result;
1814 }
1815 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1816 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1817 {
1818 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1819
1820 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1821 mpfi_atanh(result.backend().value().data(), arg.backend().value().data());
1822 return result;
1823 }
1824 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1825 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1826 {
1827 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1828
1829 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1830 mpfi_cbrt(result.backend().value().data(), arg.backend().value().data());
1831 return result;
1832 }
1833 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1834 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1835 {
1836 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1837
1838 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1839 mpfi_expm1(result.backend().value().data(), arg.backend().value().data());
1840 return result;
1841 }
1842 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1843 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>& arg)
1844 {
1845 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<mpfi_float_backend<Digits10> >, ExpressionTemplates> > precision_guard(arg);
1846
1847 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> result;
1848 mpfi_log1p(result.backend().value().data(), arg.backend().value().data());
1849 return result;
1850 }
1851
1852 }
1853
1854 namespace math {
1855
1856 namespace tools {
1857
1858 inline void set_output_precision(const boost::multiprecision::mpfi_float& val, std::ostream& os)
1859 {
1860 os << std::setprecision(val.precision());
1861 }
1862
1863 template <>
1864 inline int digits<boost::multiprecision::mpfi_float>()
1865 #ifdef BOOST_MATH_NOEXCEPT
1866 noexcept
1867 #endif
1868 {
1869 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfi_float::thread_default_precision());
1870 }
1871 template <>
1872 inline int digits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
1873 #ifdef BOOST_MATH_NOEXCEPT
1874 noexcept
1875 #endif
1876 {
1877 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfi_float::thread_default_precision());
1878 }
1879
1880 template <>
1881 inline boost::multiprecision::mpfi_float
1882 max_value<boost::multiprecision::mpfi_float>()
1883 {
1884 boost::multiprecision::mpfi_float result(0.5);
1885 mpfi_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax());
1886
1887 return result;
1888 }
1889
1890 template <>
1891 inline boost::multiprecision::mpfi_float
1892 min_value<boost::multiprecision::mpfi_float>()
1893 {
1894 boost::multiprecision::mpfi_float result(0.5);
1895 mpfi_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin());
1896
1897 return result;
1898 }
1899
1900 template <>
1901 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off>
1902 max_value<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
1903 {
1904 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> result(0.5);
1905 mpfi_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax());
1906
1907 return result;
1908 }
1909
1910 template <>
1911 inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off>
1912 min_value<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
1913 {
1914 boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> result(0.5);
1915 mpfi_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin());
1916
1917 return result;
1918 }
1919
1920
1921 using logged_type1 = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_on> ;
1922 using logged_type2 = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_off>;
1923
1924 template <>
1925 inline int digits<logged_type1>()
1926 #ifdef BOOST_MATH_NOEXCEPT
1927 noexcept
1928 #endif
1929 {
1930 return multiprecision::detail::digits10_2_2(logged_type1::thread_default_precision());
1931 }
1932 template <>
1933 inline int digits<logged_type2>()
1934 #ifdef BOOST_MATH_NOEXCEPT
1935 noexcept
1936 #endif
1937 {
1938 return multiprecision::detail::digits10_2_2(logged_type1::thread_default_precision());
1939 }
1940
1941 template <>
1942 inline logged_type1
1943 max_value<logged_type1>()
1944 {
1945 logged_type1 result(0.5);
1946 mpfi_mul_2exp(result.backend().value().data(), result.backend().value().data(), mpfr_get_emax());
1947
1948 return result;
1949 }
1950
1951 template <>
1952 inline logged_type1
1953 min_value<logged_type1>()
1954 {
1955 logged_type1 result(0.5);
1956 mpfi_div_2exp(result.backend().value().data(), result.backend().value().data(), -mpfr_get_emin());
1957
1958 return result;
1959 }
1960
1961 template <>
1962 inline logged_type2
1963 max_value<logged_type2>()
1964 {
1965 logged_type2 result(0.5);
1966 mpfi_mul_2exp(result.backend().value().data(), result.backend().value().data(), mpfr_get_emax());
1967
1968 return result;
1969 }
1970
1971 template <>
1972 inline logged_type2
1973 min_value<logged_type2>()
1974 {
1975 logged_type2 result(0.5);
1976 mpfi_div_2exp(result.backend().value().data(), result.backend().value().data(), -mpfr_get_emin());
1977
1978 return result;
1979 }
1980
1981 using debug_type1 = boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_on> ;
1982 using debug_type2 = boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_off>;
1983
1984 template <>
1985 inline int digits<debug_type1>()
1986 #ifdef BOOST_MATH_NOEXCEPT
1987 noexcept
1988 #endif
1989 {
1990 return multiprecision::detail::digits10_2_2(debug_type1::default_precision());
1991 }
1992 template <>
1993 inline int digits<debug_type2>()
1994 #ifdef BOOST_MATH_NOEXCEPT
1995 noexcept
1996 #endif
1997 {
1998 return multiprecision::detail::digits10_2_2(debug_type1::default_precision());
1999 }
2000
2001 template <>
2002 inline debug_type1
2003 max_value<debug_type1>()
2004 {
2005 debug_type1 result(0.5);
2006 mpfi_mul_2exp(result.backend().value().data(), result.backend().value().data(), mpfr_get_emax());
2007
2008 result.backend().update_view();
2009 return result;
2010 }
2011
2012 template <>
2013 inline debug_type1
2014 min_value<debug_type1>()
2015 {
2016 debug_type1 result(0.5);
2017 mpfi_div_2exp(result.backend().value().data(), result.backend().value().data(), -mpfr_get_emin());
2018
2019 result.backend().update_view();
2020 return result;
2021 }
2022
2023 template <>
2024 inline debug_type2
2025 max_value<debug_type2>()
2026 {
2027 debug_type2 result(0.5);
2028 mpfi_mul_2exp(result.backend().value().data(), result.backend().value().data(), mpfr_get_emax());
2029
2030 result.backend().update_view();
2031 return result;
2032 }
2033
2034 template <>
2035 inline debug_type2
2036 min_value<debug_type2>()
2037 {
2038 debug_type2 result(0.5);
2039 mpfi_div_2exp(result.backend().value().data(), result.backend().value().data(), -mpfr_get_emin());
2040
2041 result.backend().update_view();
2042 return result;
2043 }
2044
2045 }
2046
2047 namespace constants { namespace detail {
2048
2049 template <class T>
2050 struct constant_pi;
2051 template <class T>
2052 struct constant_ln_two;
2053 template <class T>
2054 struct constant_euler;
2055 template <class T>
2056 struct constant_catalan;
2057
2058 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2059 struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
2060 {
2061 using result_type = boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>;
2062 template <int N>
2063 static inline const result_type& get(const std::integral_constant<int, N>&)
2064 {
2065
2066 static result_type result{get(std::integral_constant<int, 0>())};
2067 return result;
2068 }
2069 static inline result_type get(const std::integral_constant<int, 0>&)
2070 {
2071 result_type result;
2072 mpfi_const_pi(result.backend().data());
2073 return result;
2074 }
2075 };
2076 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2077 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
2078 {
2079 using result_type = boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>;
2080 template <int N>
2081 static inline const result_type& get(const std::integral_constant<int, N>&)
2082 {
2083
2084 static result_type result{get(std::integral_constant<int, 0>())};
2085 return result;
2086 }
2087 static inline result_type get(const std::integral_constant<int, 0>&)
2088 {
2089 result_type result;
2090 mpfi_const_log2(result.backend().data());
2091 return result;
2092 }
2093 };
2094 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2095 struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
2096 {
2097 using result_type = boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>;
2098 template <int N>
2099 static inline const result_type& get(const std::integral_constant<int, N>&)
2100 {
2101
2102 static result_type result{get(std::integral_constant<int, 0>())};
2103 return result;
2104 }
2105 static inline result_type get(const std::integral_constant<int, 0>&)
2106 {
2107 result_type result;
2108 mpfi_const_euler(result.backend().data());
2109 return result;
2110 }
2111 };
2112 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2113 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
2114 {
2115 using result_type = boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>;
2116 template <int N>
2117 static inline const result_type& get(const std::integral_constant<int, N>&)
2118 {
2119
2120 static result_type result{get(std::integral_constant<int, 0>())};
2121 return result;
2122 }
2123 static inline result_type get(const std::integral_constant<int, 0>&)
2124 {
2125 result_type result;
2126 mpfi_const_catalan(result.backend().data());
2127 return result;
2128 }
2129 };
2130
2131
2132
2133 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2134 struct constant_pi<boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> >
2135 {
2136 using result_type = boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>;
2137 template <int N>
2138 static inline const result_type& get(const std::integral_constant<int, N>&)
2139 {
2140
2141 static result_type result{get(std::integral_constant<int, 0>())};
2142 return result;
2143 }
2144 static inline result_type get(const std::integral_constant<int, 0>&)
2145 {
2146 result_type result;
2147 mpfi_const_pi(result.backend().value().data());
2148 result.backend().update_view();
2149 return result;
2150 }
2151 };
2152 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2153 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> >
2154 {
2155 using result_type = boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>;
2156 template <int N>
2157 static inline const result_type& get(const std::integral_constant<int, N>&)
2158 {
2159
2160 static result_type result{get(std::integral_constant<int, 0>())};
2161 return result;
2162 }
2163 static inline result_type get(const std::integral_constant<int, 0>&)
2164 {
2165 result_type result;
2166 mpfi_const_log2(result.backend().value().data());
2167 result.backend().update_view();
2168 return result;
2169 }
2170 };
2171 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2172 struct constant_euler<boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> >
2173 {
2174 using result_type = boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>;
2175 template <int N>
2176 static inline const result_type& get(const std::integral_constant<int, N>&)
2177 {
2178
2179 static result_type result{get(std::integral_constant<int, 0>())};
2180 return result;
2181 }
2182 static inline result_type get(const std::integral_constant<int, 0>&)
2183 {
2184 result_type result;
2185 mpfi_const_euler(result.backend().value().data());
2186 result.backend().update_view();
2187 return result;
2188 }
2189 };
2190 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2191 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> >
2192 {
2193 using result_type = boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>;
2194 template <int N>
2195 static inline const result_type& get(const std::integral_constant<int, N>&)
2196 {
2197
2198 static result_type result{get(std::integral_constant<int, 0>())};
2199 return result;
2200 }
2201 static inline result_type get(const std::integral_constant<int, 0>&)
2202 {
2203 result_type result;
2204 mpfi_const_catalan(result.backend().value().data());
2205 result.backend().update_view();
2206 return result;
2207 }
2208 };
2209
2210
2211
2212 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2213 struct constant_pi<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> >
2214 {
2215 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>;
2216 template <int N>
2217 static inline const result_type& get(const std::integral_constant<int, N>&)
2218 {
2219
2220 static result_type result{get(std::integral_constant<int, 0>())};
2221 return result;
2222 }
2223 static inline result_type get(const std::integral_constant<int, 0>&)
2224 {
2225 result_type result;
2226 mpfi_const_pi(result.backend().value().data());
2227 return result;
2228 }
2229 };
2230 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2231 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> >
2232 {
2233 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>;
2234 template <int N>
2235 static inline const result_type& get(const std::integral_constant<int, N>&)
2236 {
2237
2238 static result_type result{get(std::integral_constant<int, 0>())};
2239 return result;
2240 }
2241 static inline result_type get(const std::integral_constant<int, 0>&)
2242 {
2243 result_type result;
2244 mpfi_const_log2(result.backend().value().data());
2245 return result;
2246 }
2247 };
2248 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2249 struct constant_euler<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> >
2250 {
2251 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>;
2252 template <int N>
2253 static inline const result_type& get(const std::integral_constant<int, N>&)
2254 {
2255
2256 static result_type result{get(std::integral_constant<int, 0>())};
2257 return result;
2258 }
2259 static inline result_type get(const std::integral_constant<int, 0>&)
2260 {
2261 result_type result;
2262 mpfi_const_euler(result.backend().value().data());
2263 return result;
2264 }
2265 };
2266 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2267 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates> >
2268 {
2269 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float_backend<Digits10> >, ExpressionTemplates>;
2270 template <int N>
2271 static inline const result_type& get(const std::integral_constant<int, N>&)
2272 {
2273
2274 static result_type result{get(std::integral_constant<int, 0>())};
2275 return result;
2276 }
2277 static inline result_type get(const std::integral_constant<int, 0>&)
2278 {
2279 result_type result;
2280 mpfi_const_catalan(result.backend().value().data());
2281 return result;
2282 }
2283 };
2284
2285 }}
2286
2287 }
2288 }
2289
2290 namespace std {
2291
2292
2293
2294
2295 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2296 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
2297 {
2298 using number_type = boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates>;
2299 static number_type get_min()
2300 {
2301 number_type value(0.5);
2302 mpfi_div_2exp(value.backend().data(), value.backend().data(), -mpfr_get_emin());
2303 return value;
2304 }
2305 static number_type get_max()
2306 {
2307 number_type value(0.5);
2308 mpfi_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax());
2309 return value;
2310 }
2311 static number_type get_epsilon()
2312 {
2313 number_type value(1);
2314 mpfi_div_2exp(value.backend().data(), value.backend().data(), std::numeric_limits<number_type>::digits - 1);
2315 return value;
2316 }
2317 static number_type get_infinity()
2318 {
2319 number_type value;
2320 boost::multiprecision::mpfr_float_backend<Digits10> t;
2321 mpfr_set_inf(t.data(), 1);
2322 mpfi_set_fr(value.backend().data(), t.data());
2323 return value;
2324 }
2325 static number_type get_quiet_NaN()
2326 {
2327 number_type value;
2328 boost::multiprecision::mpfr_float_backend<Digits10> t;
2329 mpfr_set_nan(t.data());
2330 mpfi_set_fr(value.backend().data(), t.data());
2331 return value;
2332 }
2333
2334 public:
2335 static constexpr bool is_specialized = true;
2336 static number_type(min)()
2337 {
2338 static number_type value{get_min()};
2339 return value;
2340 }
2341 static number_type(max)()
2342 {
2343 static number_type value{get_max()};
2344 return value;
2345 }
2346 static constexpr number_type lowest()
2347 {
2348 return -(max)();
2349 }
2350 static constexpr int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
2351 static constexpr int digits10 = Digits10;
2352
2353 static constexpr int max_digits10 = boost::multiprecision::detail::calc_max_digits10<digits>::value;
2354 static constexpr bool is_signed = true;
2355 static constexpr bool is_integer = false;
2356 static constexpr bool is_exact = false;
2357 static constexpr int radix = 2;
2358 static number_type epsilon()
2359 {
2360 static number_type value{get_epsilon()};
2361 return value;
2362 }
2363
2364 static number_type round_error()
2365 {
2366 return 0.5;
2367 }
2368 static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
2369 static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
2370 static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
2371 static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
2372 static constexpr bool has_infinity = true;
2373 static constexpr bool has_quiet_NaN = true;
2374 static constexpr bool has_signaling_NaN = false;
2375 static constexpr float_denorm_style has_denorm = denorm_absent;
2376 static constexpr bool has_denorm_loss = false;
2377 static number_type infinity()
2378 {
2379 static number_type value{get_infinity()};
2380 return value;
2381 }
2382 static number_type quiet_NaN()
2383 {
2384 static number_type value{get_quiet_NaN()};
2385 return value;
2386 }
2387 static constexpr number_type signaling_NaN()
2388 {
2389 return number_type(0);
2390 }
2391 static constexpr number_type denorm_min() { return (min)(); }
2392 static constexpr bool is_iec559 = false;
2393 static constexpr bool is_bounded = true;
2394 static constexpr bool is_modulo = false;
2395 static constexpr bool traps = true;
2396 static constexpr bool tinyness_before = false;
2397 static constexpr float_round_style round_style = round_to_nearest;
2398 };
2399
2400 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2401 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits;
2402 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2403 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits10;
2404 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2405 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_digits10;
2406 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2407 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_signed;
2408 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2409 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_integer;
2410 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2411 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_exact;
2412 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2413 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::radix;
2414 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2415 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent;
2416 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2417 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent10;
2418 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2419 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent;
2420 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2421 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent10;
2422 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2423 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_infinity;
2424 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2425 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
2426 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2427 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
2428 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2429 constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm;
2430 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2431 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm_loss;
2432 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2433 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_iec559;
2434 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2435 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_bounded;
2436 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2437 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_modulo;
2438 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2439 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::traps;
2440 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2441 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::tinyness_before;
2442 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
2443 constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::round_style;
2444
2445 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2446 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >
2447 {
2448 using number_type = boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates>;
2449
2450 public:
2451 static constexpr bool is_specialized = false;
2452 static number_type(min)() { return number_type(0); }
2453 static number_type(max)() { return number_type(0); }
2454 static number_type lowest() { return number_type(0); }
2455 static constexpr int digits = 0;
2456 static constexpr int digits10 = 0;
2457 static constexpr int max_digits10 = 0;
2458 static constexpr bool is_signed = false;
2459 static constexpr bool is_integer = false;
2460 static constexpr bool is_exact = false;
2461 static constexpr int radix = 0;
2462 static number_type epsilon() { return number_type(0); }
2463 static number_type round_error() { return number_type(0); }
2464 static constexpr int min_exponent = 0;
2465 static constexpr int min_exponent10 = 0;
2466 static constexpr int max_exponent = 0;
2467 static constexpr int max_exponent10 = 0;
2468 static constexpr bool has_infinity = false;
2469 static constexpr bool has_quiet_NaN = false;
2470 static constexpr bool has_signaling_NaN = false;
2471 static constexpr float_denorm_style has_denorm = denorm_absent;
2472 static constexpr bool has_denorm_loss = false;
2473 static number_type infinity() { return number_type(0); }
2474 static number_type quiet_NaN() { return number_type(0); }
2475 static number_type signaling_NaN() { return number_type(0); }
2476 static number_type denorm_min() { return number_type(0); }
2477 static constexpr bool is_iec559 = false;
2478 static constexpr bool is_bounded = false;
2479 static constexpr bool is_modulo = false;
2480 static constexpr bool traps = false;
2481 static constexpr bool tinyness_before = false;
2482 static constexpr float_round_style round_style = round_toward_zero;
2483 };
2484
2485 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2486 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits;
2487 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2488 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits10;
2489 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2490 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_digits10;
2491 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2492 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_signed;
2493 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2494 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_integer;
2495 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2496 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_exact;
2497 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2498 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::radix;
2499 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2500 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent;
2501 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2502 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent10;
2503 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2504 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent;
2505 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2506 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent10;
2507 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2508 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_infinity;
2509 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2510 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
2511 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2512 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
2513 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2514 constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm;
2515 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2516 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
2517 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2518 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_iec559;
2519 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2520 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_bounded;
2521 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2522 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_modulo;
2523 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2524 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::traps;
2525 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2526 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::tinyness_before;
2527 template <boost::multiprecision::expression_template_option ExpressionTemplates>
2528 constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::round_style;
2529
2530 }
2531 #endif