File indexing completed on 2025-09-16 08:41:00
0001
0002
0003
0004
0005
0006 #ifndef BOOST_MP_MPFR_HPP
0007 #define BOOST_MP_MPFR_HPP
0008
0009 #include <boost/multiprecision/detail/standalone_config.hpp>
0010 #include <boost/multiprecision/number.hpp>
0011 #include <boost/multiprecision/debug_adaptor.hpp>
0012 #include <boost/multiprecision/logged_adaptor.hpp>
0013 #include <boost/multiprecision/gmp.hpp>
0014 #include <boost/multiprecision/detail/digits.hpp>
0015 #include <boost/multiprecision/detail/float128_functions.hpp>
0016 #include <boost/multiprecision/detail/atomic.hpp>
0017 #include <boost/multiprecision/traits/max_digits10.hpp>
0018 #include <boost/multiprecision/detail/hash.hpp>
0019 #include <boost/multiprecision/detail/no_exceptions_support.hpp>
0020 #include <boost/multiprecision/detail/assert.hpp>
0021 #include <boost/multiprecision/detail/fpclassify.hpp>
0022 #include <mpfr.h>
0023 #include <cmath>
0024 #include <cstdint>
0025 #include <algorithm>
0026 #include <utility>
0027 #include <type_traits>
0028 #include <atomic>
0029
0030 #ifdef BOOST_MP_MATH_AVAILABLE
0031 #include <boost/math/constants/constants.hpp>
0032 #include <boost/math/special_functions/gamma.hpp>
0033 #endif
0034
0035 #ifndef BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION
0036 #define BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION 20
0037 #endif
0038
0039 namespace boost {
0040 namespace multiprecision {
0041
0042 template <unsigned digits10, mpfr_allocation_type AllocationType>
0043 struct number_category<backends::mpfr_float_backend<digits10, AllocationType> > : public std::integral_constant<int, number_kind_floating_point>
0044 {};
0045
0046 namespace backends {
0047
0048 namespace detail {
0049
0050 template <bool b>
0051 struct mpfr_cleanup
0052 {
0053
0054
0055
0056
0057
0058
0059 struct initializer
0060 {
0061 initializer() {}
0062 ~initializer() { mpfr_free_cache(); }
0063 void force_instantiate() const {}
0064 };
0065 #if MPFR_VERSION_MAJOR >= 4
0066 struct thread_initializer
0067 {
0068 thread_initializer() {}
0069 ~thread_initializer() { mpfr_free_cache2(MPFR_FREE_LOCAL_CACHE); }
0070 void force_instantiate() const {}
0071 };
0072 #endif
0073 static const initializer init;
0074 static void force_instantiate()
0075 {
0076 #if MPFR_VERSION_MAJOR >= 4
0077 static const BOOST_MP_THREAD_LOCAL thread_initializer thread_init;
0078 thread_init.force_instantiate();
0079 #endif
0080 init.force_instantiate();
0081 }
0082 };
0083
0084 template <bool b>
0085 typename mpfr_cleanup<b>::initializer const mpfr_cleanup<b>::init;
0086
0087 inline void mpfr_copy_precision(mpfr_t dest, const mpfr_t src)
0088 {
0089 mpfr_prec_t p_dest = mpfr_get_prec(dest);
0090 mpfr_prec_t p_src = mpfr_get_prec(src);
0091 if (p_dest != p_src)
0092 mpfr_set_prec(dest, p_src);
0093 }
0094 inline void mpfr_copy_precision(mpfr_t dest, const mpfr_t src1, const mpfr_t src2)
0095 {
0096 mpfr_prec_t p_dest = mpfr_get_prec(dest);
0097 mpfr_prec_t p_src1 = mpfr_get_prec(src1);
0098 mpfr_prec_t p_src2 = mpfr_get_prec(src2);
0099 if (p_src2 > p_src1)
0100 p_src1 = p_src2;
0101 if (p_dest != p_src1)
0102 mpfr_set_prec(dest, p_src1);
0103 }
0104
0105 template <unsigned digits10, mpfr_allocation_type AllocationType>
0106 struct mpfr_float_imp;
0107
0108 template <unsigned digits10>
0109 struct mpfr_float_imp<digits10, allocate_dynamic>
0110 {
0111 #ifdef BOOST_HAS_LONG_LONG
0112 using signed_types = std::tuple<long, long long> ;
0113 using unsigned_types = std::tuple<unsigned long, unsigned long long>;
0114 #else
0115 using signed_types = std::tuple<long> ;
0116 using unsigned_types = std::tuple<unsigned long>;
0117 #endif
0118 using float_types = std::tuple<double, long double>;
0119 using exponent_type = long ;
0120
0121 mpfr_float_imp()
0122 {
0123 mpfr_init2(m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision()))));
0124 mpfr_set_ui(m_data, 0u, GMP_RNDN);
0125 }
0126 mpfr_float_imp(unsigned digits2)
0127 {
0128 mpfr_init2(m_data, digits2);
0129 mpfr_set_ui(m_data, 0u, GMP_RNDN);
0130 }
0131
0132 mpfr_float_imp(const mpfr_float_imp& o)
0133 {
0134 mpfr_init2(m_data, preserve_source_precision() ? mpfr_get_prec(o.data()) : static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision())));
0135 if (o.m_data[0]._mpfr_d)
0136 mpfr_set(m_data, o.m_data, GMP_RNDN);
0137 }
0138
0139 mpfr_float_imp(mpfr_float_imp&& o) noexcept
0140 {
0141 mpfr_prec_t binary_default_precision = static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision()));
0142 if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpfr_get_prec(o.data()) == binary_default_precision))
0143 {
0144 m_data[0] = o.m_data[0];
0145 o.m_data[0]._mpfr_d = nullptr;
0146 }
0147 else
0148 {
0149
0150 mpfr_init2(m_data, binary_default_precision);
0151 if (o.m_data[0]._mpfr_d)
0152 mpfr_set(m_data, o.m_data, GMP_RNDN);
0153 }
0154 }
0155 mpfr_float_imp& operator=(const mpfr_float_imp& o)
0156 {
0157 if ((o.m_data[0]._mpfr_d) && (this != &o))
0158 {
0159 if (m_data[0]._mpfr_d == nullptr)
0160 {
0161 mpfr_init2(m_data, preserve_source_precision() ? static_cast<mpfr_prec_t>(mpfr_get_prec(o.m_data)) : static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision())));
0162 }
0163 else if (preserve_source_precision() && (mpfr_get_prec(o.data()) != mpfr_get_prec(data())))
0164 {
0165 mpfr_set_prec(m_data, mpfr_get_prec(o.m_data));
0166 }
0167 mpfr_set(m_data, o.m_data, GMP_RNDN);
0168 }
0169 return *this;
0170 }
0171
0172 mpfr_float_imp& operator=(mpfr_float_imp&& o) noexcept
0173 {
0174 if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpfr_get_prec(o.data()) == mpfr_get_prec(data())))
0175 mpfr_swap(m_data, o.m_data);
0176 else
0177 *this = static_cast<const mpfr_float_imp&>(o);
0178 return *this;
0179 }
0180 #ifdef BOOST_HAS_LONG_LONG
0181 #ifdef _MPFR_H_HAVE_INTMAX_T
0182 mpfr_float_imp& operator=(unsigned long long i)
0183 {
0184 if (m_data[0]._mpfr_d == nullptr)
0185 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0186 mpfr_set_uj(m_data, i, GMP_RNDN);
0187 return *this;
0188 }
0189 mpfr_float_imp& operator=(long long i)
0190 {
0191 if (m_data[0]._mpfr_d == nullptr)
0192 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0193 mpfr_set_sj(m_data, i, GMP_RNDN);
0194 return *this;
0195 }
0196 #else
0197 mpfr_float_imp& operator=(unsigned long long i)
0198 {
0199 if (m_data[0]._mpfr_d == nullptr)
0200 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0201 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
0202 unsigned shift = 0;
0203 mpfr_t t;
0204 mpfr_init2(t, (std::max)(static_cast<mpfr_prec_t>(std::numeric_limits<unsigned long long>::digits), static_cast<mpfr_prec_t>(mpfr_get_prec(m_data))));
0205 mpfr_set_ui(m_data, 0, GMP_RNDN);
0206 while (i)
0207 {
0208 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
0209 if (shift)
0210 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
0211 mpfr_add(m_data, m_data, t, GMP_RNDN);
0212 shift += std::numeric_limits<unsigned long>::digits;
0213 i >>= std::numeric_limits<unsigned long>::digits;
0214 }
0215 mpfr_clear(t);
0216 return *this;
0217 }
0218 mpfr_float_imp& operator=(long long i)
0219 {
0220 if (m_data[0]._mpfr_d == nullptr)
0221 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0222 bool neg = i < 0;
0223 *this = boost::multiprecision::detail::unsigned_abs(i);
0224 if (neg)
0225 mpfr_neg(m_data, m_data, GMP_RNDN);
0226 return *this;
0227 }
0228 #endif
0229 #endif
0230 #ifdef BOOST_HAS_INT128
0231 mpfr_float_imp& operator=(uint128_type i)
0232 {
0233 if (m_data[0]._mpfr_d == nullptr)
0234 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0235 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
0236 unsigned shift = 0;
0237 mpfr_t t;
0238 mpfr_init2(t, (std::max)(static_cast<mpfr_prec_t>(std::numeric_limits<unsigned long long>::digits), static_cast<mpfr_prec_t>(mpfr_get_prec(m_data))));
0239 mpfr_set_ui(m_data, 0, GMP_RNDN);
0240 while (i)
0241 {
0242 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
0243 if (shift)
0244 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
0245 mpfr_add(m_data, m_data, t, GMP_RNDN);
0246 shift += std::numeric_limits<unsigned long>::digits;
0247 i >>= std::numeric_limits<unsigned long>::digits;
0248 }
0249 mpfr_clear(t);
0250 return *this;
0251 }
0252 mpfr_float_imp& operator=(int128_type i)
0253 {
0254 if (m_data[0]._mpfr_d == nullptr)
0255 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0256 bool neg = i < 0;
0257 *this = boost::multiprecision::detail::unsigned_abs(i);
0258 if (neg)
0259 mpfr_neg(m_data, m_data, GMP_RNDN);
0260 return *this;
0261 }
0262 #endif
0263 mpfr_float_imp& operator=(unsigned long i)
0264 {
0265 if (m_data[0]._mpfr_d == nullptr)
0266 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0267 mpfr_set_ui(m_data, i, GMP_RNDN);
0268 return *this;
0269 }
0270 mpfr_float_imp& operator=(long i)
0271 {
0272 if (m_data[0]._mpfr_d == nullptr)
0273 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0274 mpfr_set_si(m_data, i, GMP_RNDN);
0275 return *this;
0276 }
0277 mpfr_float_imp& operator=(double d)
0278 {
0279 if (m_data[0]._mpfr_d == nullptr)
0280 mpfr_init2(m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision()))));
0281 mpfr_set_d(m_data, d, GMP_RNDN);
0282 return *this;
0283 }
0284 mpfr_float_imp& operator=(long double a)
0285 {
0286 if (m_data[0]._mpfr_d == nullptr)
0287 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0288 mpfr_set_ld(m_data, a, GMP_RNDN);
0289 return *this;
0290 }
0291 #ifdef BOOST_HAS_FLOAT128
0292 mpfr_float_imp& operator=(float128_type a)
0293 {
0294 BOOST_MP_FLOAT128_USING
0295 if (m_data[0]._mpfr_d == nullptr)
0296 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
0297
0298 if (a == 0)
0299 {
0300 mpfr_set_si(m_data, 0, GMP_RNDN);
0301 return *this;
0302 }
0303
0304 if (a == 1)
0305 {
0306 mpfr_set_si(m_data, 1, GMP_RNDN);
0307 return *this;
0308 }
0309
0310 if (BOOST_MP_ISINF(a))
0311 {
0312 mpfr_set_inf(m_data, a < 0 ? -1 : 1);
0313 return *this;
0314 }
0315 if (BOOST_MP_ISNAN(a))
0316 {
0317 mpfr_set_nan(m_data);
0318 return *this;
0319 }
0320
0321 int e;
0322 float128_type f, term;
0323 mpfr_set_ui(m_data, 0u, GMP_RNDN);
0324
0325 f = frexp(a, &e);
0326
0327 constexpr const int shift = std::numeric_limits<int>::digits - 1;
0328
0329 while (f)
0330 {
0331
0332 f = ldexp(f, shift);
0333 term = floor(f);
0334 e -= shift;
0335 mpfr_mul_2exp(m_data, m_data, shift, GMP_RNDN);
0336 if (term > 0)
0337 mpfr_add_ui(m_data, m_data, static_cast<unsigned>(term), GMP_RNDN);
0338 else
0339 mpfr_sub_ui(m_data, m_data, static_cast<unsigned>(-term), GMP_RNDN);
0340 f -= term;
0341 }
0342 if (e > 0)
0343 mpfr_mul_2exp(m_data, m_data, e, GMP_RNDN);
0344 else if (e < 0)
0345 mpfr_div_2exp(m_data, m_data, -e, GMP_RNDN);
0346 return *this;
0347 }
0348 #endif
0349 mpfr_float_imp& operator=(const char* s)
0350 {
0351 if (m_data[0]._mpfr_d == nullptr)
0352 mpfr_init2(m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision()))));
0353 if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
0354 {
0355 BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
0356 }
0357 return *this;
0358 }
0359 void swap(mpfr_float_imp& o) noexcept
0360 {
0361 mpfr_swap(m_data, o.m_data);
0362 }
0363 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
0364 {
0365 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0366
0367 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
0368 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
0369
0370 std::streamsize org_digits(digits);
0371
0372 if (scientific && digits)
0373 ++digits;
0374
0375 std::string result;
0376 mp_exp_t e;
0377 if (mpfr_inf_p(m_data))
0378 {
0379 if (mpfr_sgn(m_data) < 0)
0380 result = "-inf";
0381 else if (f & std::ios_base::showpos)
0382 result = "+inf";
0383 else
0384 result = "inf";
0385 return result;
0386 }
0387 if (mpfr_nan_p(m_data))
0388 {
0389 result = "nan";
0390 return result;
0391 }
0392 if (mpfr_zero_p(m_data))
0393 {
0394 e = 0;
0395 if (mpfr_signbit(m_data))
0396 result = "-0";
0397 else
0398 result = "0";
0399 }
0400 else if (fixed)
0401 {
0402
0403 char* ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
0404 --e;
0405 mpfr_free_str(ps);
0406 digits += e + 1;
0407 if (digits == 0)
0408 {
0409
0410
0411 ps = mpfr_get_str(nullptr, &e, 10, 0, m_data, GMP_RNDN);
0412 --e;
0413 unsigned offset = *ps == '-' ? 1 : 0;
0414 if (ps[offset] > '5')
0415 {
0416 ++e;
0417 ps[offset] = '1';
0418 ps[offset + 1] = 0;
0419 }
0420 else if (ps[offset] == '5')
0421 {
0422 unsigned i = offset + 1;
0423 bool round_up = false;
0424 while (ps[i] != 0)
0425 {
0426 if (ps[i] != '0')
0427 {
0428 round_up = true;
0429 break;
0430 }
0431 ++i;
0432 }
0433 if (round_up)
0434 {
0435 ++e;
0436 ps[offset] = '1';
0437 ps[offset + 1] = 0;
0438 }
0439 else
0440 {
0441 ps[offset] = '0';
0442 ps[offset + 1] = 0;
0443 }
0444 }
0445 else
0446 {
0447 ps[offset] = '0';
0448 ps[offset + 1] = 0;
0449 }
0450 }
0451 else if (digits > 0)
0452 {
0453 mp_exp_t old_e = e;
0454 ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
0455 --e;
0456 if (old_e > e)
0457 {
0458
0459
0460
0461
0462 mpfr_free_str(ps);
0463 digits -= old_e - e;
0464 ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
0465 --e;
0466 }
0467 }
0468 else
0469 {
0470 ps = mpfr_get_str(nullptr, &e, 10, 1, m_data, GMP_RNDN);
0471 --e;
0472 unsigned offset = *ps == '-' ? 1 : 0;
0473 ps[offset] = '0';
0474 ps[offset + 1] = 0;
0475 }
0476 result = ps ? ps : "0";
0477 if (ps)
0478 mpfr_free_str(ps);
0479 }
0480 else
0481 {
0482 char* ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
0483 --e;
0484 result = ps ? ps : "0";
0485 if (ps)
0486 mpfr_free_str(ps);
0487 }
0488 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
0489 return result;
0490 }
0491 ~mpfr_float_imp() noexcept
0492 {
0493 if (m_data[0]._mpfr_d)
0494 mpfr_clear(m_data);
0495 detail::mpfr_cleanup<true>::force_instantiate();
0496 }
0497 void negate() noexcept
0498 {
0499 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0500 mpfr_neg(m_data, m_data, GMP_RNDN);
0501 }
0502 template <mpfr_allocation_type AllocationType>
0503 int compare(const mpfr_float_backend<digits10, AllocationType>& o) const
0504 {
0505 BOOST_MP_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d);
0506 return mpfr_cmp(m_data, o.m_data);
0507 }
0508 int compare(long i) const
0509 {
0510 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0511 return mpfr_cmp_si(m_data, i);
0512 }
0513 int compare(double i) const
0514 {
0515 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0516 return mpfr_cmp_d(m_data, i);
0517 }
0518 int compare(long double i) const
0519 {
0520 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0521 return mpfr_cmp_ld(m_data, i);
0522 }
0523 int compare(unsigned long i) const
0524 {
0525 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0526 return mpfr_cmp_ui(m_data, i);
0527 }
0528 template <class V>
0529 int compare(V v) const
0530 {
0531 mpfr_float_backend<digits10, allocate_dynamic> d(0uL, mpfr_get_prec(m_data));
0532 d = v;
0533 return compare(d);
0534 }
0535 mpfr_t& data() noexcept
0536 {
0537 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0538 return m_data;
0539 }
0540 const mpfr_t& data() const noexcept
0541 {
0542 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0543 return m_data;
0544 }
0545
0546 protected:
0547 mpfr_t m_data;
0548 static boost::multiprecision::detail::precision_type& get_global_default_precision() noexcept
0549 {
0550 static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION);
0551 return val;
0552 }
0553 static unsigned& get_default_precision() noexcept
0554 {
0555 static BOOST_MP_THREAD_LOCAL unsigned val(get_global_default_precision());
0556 return val;
0557 }
0558 #ifndef BOOST_MT_NO_ATOMIC_INT
0559 static std::atomic<variable_precision_options>& get_global_default_options() noexcept
0560 {
0561 static std::atomic<variable_precision_options> val{variable_precision_options::preserve_related_precision};
0562 return val;
0563 }
0564 #else
0565 static variable_precision_options& get_global_default_options() noexcept
0566 {
0567 static variable_precision_options val{variable_precision_options::preserve_related_precision};
0568 return val;
0569 }
0570 #endif
0571 static variable_precision_options& get_default_options()noexcept
0572 {
0573 static BOOST_MP_THREAD_LOCAL variable_precision_options val(get_global_default_options());
0574 return val;
0575 }
0576 static bool preserve_source_precision() noexcept
0577 {
0578 return get_default_options() >= variable_precision_options::preserve_source_precision;
0579 }
0580 };
0581
0582 #ifdef BOOST_MSVC
0583 #pragma warning(push)
0584 #pragma warning(disable : 4127)
0585 #endif
0586
0587 template <unsigned digits10>
0588 struct mpfr_float_imp<digits10, allocate_stack>
0589 {
0590 #ifdef BOOST_HAS_LONG_LONG
0591 using signed_types = std::tuple<long, long long> ;
0592 using unsigned_types = std::tuple<unsigned long, unsigned long long>;
0593 #else
0594 using signed_types = std::tuple<long> ;
0595 using unsigned_types = std::tuple<unsigned long>;
0596 #endif
0597 using float_types = std::tuple<double, long double>;
0598 using exponent_type = long ;
0599
0600 static constexpr const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u);
0601 static constexpr const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t);
0602
0603 ~mpfr_float_imp() noexcept
0604 {
0605 detail::mpfr_cleanup<true>::force_instantiate();
0606 }
0607 mpfr_float_imp()
0608 {
0609 mpfr_custom_init(m_buffer, digits2);
0610 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
0611 mpfr_set_ui(m_data, 0u, GMP_RNDN);
0612 }
0613
0614 mpfr_float_imp(const mpfr_float_imp& o)
0615 {
0616 mpfr_custom_init(m_buffer, digits2);
0617 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
0618 mpfr_set(m_data, o.m_data, GMP_RNDN);
0619 }
0620 mpfr_float_imp& operator=(const mpfr_float_imp& o)
0621 {
0622 mpfr_set(m_data, o.m_data, GMP_RNDN);
0623 return *this;
0624 }
0625 #ifdef BOOST_HAS_LONG_LONG
0626 #ifdef _MPFR_H_HAVE_INTMAX_T
0627 mpfr_float_imp& operator=(unsigned long long i)
0628 {
0629 mpfr_set_uj(m_data, i, GMP_RNDN);
0630 return *this;
0631 }
0632 mpfr_float_imp& operator=(long long i)
0633 {
0634 mpfr_set_sj(m_data, i, GMP_RNDN);
0635 return *this;
0636 }
0637 #else
0638 mpfr_float_imp& operator=(unsigned long long i)
0639 {
0640 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL);
0641 unsigned shift = 0;
0642 mpfr_t t;
0643 mp_limb_t t_limbs[limb_count];
0644 mpfr_custom_init(t_limbs, digits2);
0645 mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
0646 mpfr_set_ui(m_data, 0, GMP_RNDN);
0647 while (i)
0648 {
0649 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
0650 if (shift)
0651 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
0652 mpfr_add(m_data, m_data, t, GMP_RNDN);
0653 shift += std::numeric_limits<unsigned long>::digits;
0654 i >>= std::numeric_limits<unsigned long>::digits;
0655 }
0656 return *this;
0657 }
0658 mpfr_float_imp& operator=(long long i)
0659 {
0660 bool neg = i < 0;
0661 *this = boost::multiprecision::detail::unsigned_abs(i);
0662 if (neg)
0663 mpfr_neg(m_data, m_data, GMP_RNDN);
0664 return *this;
0665 }
0666 #endif
0667 #endif
0668 #ifdef BOOST_HAS_INT128
0669 mpfr_float_imp& operator=(uint128_type i)
0670 {
0671 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL);
0672 unsigned shift = 0;
0673 mpfr_t t;
0674 mp_limb_t t_limbs[limb_count];
0675 mpfr_custom_init(t_limbs, digits2);
0676 mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
0677 mpfr_set_ui(m_data, 0, GMP_RNDN);
0678 while (i)
0679 {
0680 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
0681 if (shift)
0682 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
0683 mpfr_add(m_data, m_data, t, GMP_RNDN);
0684 shift += std::numeric_limits<unsigned long>::digits;
0685 i >>= std::numeric_limits<unsigned long>::digits;
0686 }
0687 return *this;
0688 }
0689 mpfr_float_imp& operator=(int128_type i)
0690 {
0691 bool neg = i < 0;
0692 *this = boost::multiprecision::detail::unsigned_abs(i);
0693 if (neg)
0694 mpfr_neg(m_data, m_data, GMP_RNDN);
0695 return *this;
0696 }
0697 #endif
0698 mpfr_float_imp& operator=(unsigned long i)
0699 {
0700 mpfr_set_ui(m_data, i, GMP_RNDN);
0701 return *this;
0702 }
0703 mpfr_float_imp& operator=(long i)
0704 {
0705 mpfr_set_si(m_data, i, GMP_RNDN);
0706 return *this;
0707 }
0708 mpfr_float_imp& operator=(double d)
0709 {
0710 mpfr_set_d(m_data, d, GMP_RNDN);
0711 return *this;
0712 }
0713 mpfr_float_imp& operator=(long double a)
0714 {
0715 mpfr_set_ld(m_data, a, GMP_RNDN);
0716 return *this;
0717 }
0718 #ifdef BOOST_HAS_FLOAT128
0719 mpfr_float_imp& operator=(float128_type a)
0720 {
0721 BOOST_MP_FLOAT128_USING
0722 if (a == 0)
0723 {
0724 mpfr_set_si(m_data, 0, GMP_RNDN);
0725 return *this;
0726 }
0727
0728 if (a == 1)
0729 {
0730 mpfr_set_si(m_data, 1, GMP_RNDN);
0731 return *this;
0732 }
0733
0734 if (BOOST_MP_ISINF(a))
0735 {
0736 mpfr_set_inf(m_data, a < 0 ? -1 : 1);
0737 return *this;
0738 }
0739 if (BOOST_MP_ISNAN(a))
0740 {
0741 mpfr_set_nan(m_data);
0742 return *this;
0743 }
0744
0745 int e;
0746 float128_type f, term;
0747 mpfr_set_ui(m_data, 0u, GMP_RNDN);
0748
0749 f = frexp(a, &e);
0750
0751 constexpr const int shift = std::numeric_limits<int>::digits - 1;
0752
0753 while (f)
0754 {
0755
0756 f = ldexp(f, shift);
0757 term = floor(f);
0758 e -= shift;
0759 mpfr_mul_2exp(m_data, m_data, shift, GMP_RNDN);
0760 if (term > 0)
0761 mpfr_add_ui(m_data, m_data, static_cast<unsigned>(term), GMP_RNDN);
0762 else
0763 mpfr_sub_ui(m_data, m_data, static_cast<unsigned>(-term), GMP_RNDN);
0764 f -= term;
0765 }
0766 if (e > 0)
0767 mpfr_mul_2exp(m_data, m_data, e, GMP_RNDN);
0768 else if (e < 0)
0769 mpfr_div_2exp(m_data, m_data, -e, GMP_RNDN);
0770 return *this;
0771 }
0772 #endif
0773 mpfr_float_imp& operator=(const char* s)
0774 {
0775 if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
0776 {
0777 BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
0778 }
0779 return *this;
0780 }
0781 void swap(mpfr_float_imp& o) noexcept
0782 {
0783
0784 mpfr_float_imp t(*this);
0785 *this = o;
0786 o = t;
0787 }
0788 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
0789 {
0790 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
0791
0792 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
0793 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
0794
0795 std::streamsize org_digits(digits);
0796
0797 if (scientific && digits)
0798 ++digits;
0799
0800 std::string result;
0801 mp_exp_t e;
0802 if (mpfr_inf_p(m_data))
0803 {
0804 if (mpfr_sgn(m_data) < 0)
0805 result = "-inf";
0806 else if (f & std::ios_base::showpos)
0807 result = "+inf";
0808 else
0809 result = "inf";
0810 return result;
0811 }
0812 if (mpfr_nan_p(m_data))
0813 {
0814 result = "nan";
0815 return result;
0816 }
0817 if (mpfr_zero_p(m_data))
0818 {
0819 e = 0;
0820 result = "0";
0821 }
0822 else
0823 {
0824 char* ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
0825 --e;
0826 if (fixed && e != -1)
0827 {
0828
0829 mpfr_free_str(ps);
0830 digits += e + 1;
0831 if (digits == 0)
0832 {
0833
0834
0835 ps = mpfr_get_str(nullptr, &e, 10, 0, m_data, GMP_RNDN);
0836 --e;
0837 unsigned offset = *ps == '-' ? 1 : 0;
0838 if (ps[offset] > '5')
0839 {
0840 ++e;
0841 ps[offset] = '1';
0842 ps[offset + 1] = 0;
0843 }
0844 else if (ps[offset] == '5')
0845 {
0846 unsigned i = offset + 1;
0847 bool round_up = false;
0848 while (ps[i] != 0)
0849 {
0850 if (ps[i] != '0')
0851 {
0852 round_up = true;
0853 break;
0854 }
0855
0856 ++i;
0857 }
0858 if (round_up)
0859 {
0860 ++e;
0861 ps[offset] = '1';
0862 ps[offset + 1] = 0;
0863 }
0864 else
0865 {
0866 ps[offset] = '0';
0867 ps[offset + 1] = 0;
0868 }
0869 }
0870 else
0871 {
0872 ps[offset] = '0';
0873 ps[offset + 1] = 0;
0874 }
0875 }
0876 else if (digits > 0)
0877 {
0878 ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
0879 --e;
0880 }
0881 else
0882 {
0883 ps = mpfr_get_str(nullptr, &e, 10, 1, m_data, GMP_RNDN);
0884 --e;
0885 unsigned offset = *ps == '-' ? 1 : 0;
0886 ps[offset] = '0';
0887 ps[offset + 1] = 0;
0888 }
0889 }
0890 result = ps ? ps : "0";
0891 if (ps)
0892 mpfr_free_str(ps);
0893 }
0894 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
0895 return result;
0896 }
0897 void negate() noexcept
0898 {
0899 mpfr_neg(m_data, m_data, GMP_RNDN);
0900 }
0901 template <mpfr_allocation_type AllocationType>
0902 int compare(const mpfr_float_backend<digits10, AllocationType>& o) const
0903 {
0904 return mpfr_cmp(m_data, o.m_data);
0905 }
0906 int compare(long i) const
0907 {
0908 return mpfr_cmp_si(m_data, i);
0909 }
0910 int compare(unsigned long i) const
0911 {
0912 return mpfr_cmp_ui(m_data, i);
0913 }
0914 int compare(double i) const
0915 {
0916 return mpfr_cmp_d(m_data, i);
0917 }
0918 int compare(long double i) const
0919 {
0920 return mpfr_cmp_ld(m_data, i);
0921 }
0922 template <class V>
0923 int compare(V v) const
0924 {
0925 mpfr_float_backend<digits10, allocate_stack> d;
0926 d = v;
0927 return compare(d);
0928 }
0929 mpfr_t& data() noexcept
0930 {
0931 return m_data;
0932 }
0933 const mpfr_t& data() const noexcept
0934 {
0935 return m_data;
0936 }
0937
0938 protected:
0939 mpfr_t m_data;
0940 mp_limb_t m_buffer[limb_count];
0941 };
0942
0943 #ifdef BOOST_MSVC
0944 #pragma warning(pop)
0945 #endif
0946
0947 }
0948
0949 template <unsigned digits10, mpfr_allocation_type AllocationType>
0950 struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
0951 {
0952 mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
0953 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
0954
0955 mpfr_float_backend(mpfr_float_backend&& o) noexcept : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o))
0956 {}
0957 template <unsigned D, mpfr_allocation_type AT>
0958 mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
0959 : detail::mpfr_float_imp<digits10, AllocationType>()
0960 {
0961 mpfr_set(this->m_data, val.data(), GMP_RNDN);
0962 }
0963 template <unsigned D, mpfr_allocation_type AT>
0964 explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
0965 : detail::mpfr_float_imp<digits10, AllocationType>()
0966 {
0967 mpfr_set(this->m_data, val.data(), GMP_RNDN);
0968 }
0969 template <unsigned D>
0970 mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
0971 : detail::mpfr_float_imp<digits10, AllocationType>()
0972 {
0973 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
0974 }
0975 template <unsigned D>
0976 mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
0977 : detail::mpfr_float_imp<digits10, AllocationType>()
0978 {
0979 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
0980 }
0981 mpfr_float_backend(const gmp_int& val)
0982 : detail::mpfr_float_imp<digits10, AllocationType>()
0983 {
0984 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
0985 }
0986 mpfr_float_backend(const gmp_rational& val)
0987 : detail::mpfr_float_imp<digits10, AllocationType>()
0988 {
0989 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
0990 }
0991 mpfr_float_backend(const mpfr_t val)
0992 : detail::mpfr_float_imp<digits10, AllocationType>()
0993 {
0994 mpfr_set(this->m_data, val, GMP_RNDN);
0995 }
0996 mpfr_float_backend(const mpf_t val)
0997 : detail::mpfr_float_imp<digits10, AllocationType>()
0998 {
0999 mpfr_set_f(this->m_data, val, GMP_RNDN);
1000 }
1001 mpfr_float_backend(const mpz_t val)
1002 : detail::mpfr_float_imp<digits10, AllocationType>()
1003 {
1004 mpfr_set_z(this->m_data, val, GMP_RNDN);
1005 }
1006 mpfr_float_backend(const mpq_t val)
1007 : detail::mpfr_float_imp<digits10, AllocationType>()
1008 {
1009 mpfr_set_q(this->m_data, val, GMP_RNDN);
1010 }
1011
1012 template <class V>
1013 mpfr_float_backend(const V& o, unsigned)
1014 {
1015 *this = o;
1016 }
1017 mpfr_float_backend& operator=(const mpfr_float_backend& o)
1018 {
1019 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
1020 return *this;
1021 }
1022
1023 mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept
1024 {
1025 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
1026 return *this;
1027 }
1028 template <class V>
1029 typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<digits10, AllocationType>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
1030 {
1031 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
1032 return *this;
1033 }
1034 mpfr_float_backend& operator=(const mpfr_t val)
1035 {
1036 if (this->m_data[0]._mpfr_d == nullptr)
1037 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1038 mpfr_set(this->m_data, val, GMP_RNDN);
1039 return *this;
1040 }
1041 mpfr_float_backend& operator=(const mpf_t val)
1042 {
1043 if (this->m_data[0]._mpfr_d == nullptr)
1044 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1045 mpfr_set_f(this->m_data, val, GMP_RNDN);
1046 return *this;
1047 }
1048 mpfr_float_backend& operator=(const mpz_t val)
1049 {
1050 if (this->m_data[0]._mpfr_d == nullptr)
1051 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1052 mpfr_set_z(this->m_data, val, GMP_RNDN);
1053 return *this;
1054 }
1055 mpfr_float_backend& operator=(const mpq_t val)
1056 {
1057 if (this->m_data[0]._mpfr_d == nullptr)
1058 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1059 mpfr_set_q(this->m_data, val, GMP_RNDN);
1060 return *this;
1061 }
1062
1063 template <unsigned D, mpfr_allocation_type AT>
1064 mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
1065 {
1066 if (this->m_data[0]._mpfr_d == nullptr)
1067 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1068 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1069 return *this;
1070 }
1071 template <unsigned D>
1072 mpfr_float_backend& operator=(const gmp_float<D>& val)
1073 {
1074 if (this->m_data[0]._mpfr_d == nullptr)
1075 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1076 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1077 return *this;
1078 }
1079 mpfr_float_backend& operator=(const gmp_int& val)
1080 {
1081 if (this->m_data[0]._mpfr_d == nullptr)
1082 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1083 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1084 return *this;
1085 }
1086 mpfr_float_backend& operator=(const gmp_rational& val)
1087 {
1088 if (this->m_data[0]._mpfr_d == nullptr)
1089 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1090 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1091 return *this;
1092 }
1093 };
1094
1095 template <>
1096 struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
1097 {
1098 mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
1099 mpfr_float_backend(const mpfr_t val)
1100 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(mpfr_get_prec(val)) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(get_default_precision())))
1101 {
1102 mpfr_set(this->m_data, val, GMP_RNDN);
1103 }
1104 mpfr_float_backend(const mpf_t val)
1105 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(mpf_get_prec(val)) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(get_default_precision())))
1106 {
1107 mpfr_set_f(this->m_data, val, GMP_RNDN);
1108 }
1109 mpfr_float_backend(const mpz_t val)
1110 : detail::mpfr_float_imp<0, allocate_dynamic>()
1111 {
1112 mpfr_set_z(this->m_data, val, GMP_RNDN);
1113 }
1114 mpfr_float_backend(const mpq_t val)
1115 : detail::mpfr_float_imp<0, allocate_dynamic>()
1116 {
1117 mpfr_set_q(this->m_data, val, GMP_RNDN);
1118 }
1119 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
1120
1121 mpfr_float_backend(mpfr_float_backend&& o) noexcept : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o))
1122 {}
1123 template <class V>
1124 mpfr_float_backend(const V& o, unsigned digits10)
1125 : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
1126 {
1127 *this = o;
1128 }
1129 #ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
1130 mpfr_float_backend(const std::string_view& o, unsigned digits10)
1131 : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
1132 {
1133 std::string s(o);
1134 *this = s.c_str();
1135 }
1136 #endif
1137 template <unsigned D>
1138 mpfr_float_backend(const gmp_float<D>& val, unsigned digits10)
1139 : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
1140 {
1141 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1142 }
1143 template <unsigned D>
1144 mpfr_float_backend(const mpfr_float_backend<D>& val, unsigned digits10)
1145 : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
1146 {
1147 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1148 }
1149 template <unsigned D>
1150 mpfr_float_backend(const mpfr_float_backend<D>& val)
1151 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_related_precision() ? static_cast<unsigned>(mpfr_get_prec(val.data())) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(get_default_precision())))
1152 {
1153 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1154 }
1155 template <unsigned D>
1156 mpfr_float_backend(const gmp_float<D>& val)
1157 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(mpf_get_prec(val.data())) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(get_default_precision())))
1158 {
1159 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1160 }
1161 mpfr_float_backend(const gmp_int& val)
1162 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(used_gmp_int_bits(val)) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(thread_default_precision())))
1163 {
1164 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1165 }
1166 mpfr_float_backend(const gmp_rational& val)
1167 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(used_gmp_rational_bits(val)) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(thread_default_precision())))
1168 {
1169 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1170 }
1171
1172 mpfr_float_backend& operator=(const mpfr_float_backend& o) = default;
1173
1174 mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept = default;
1175
1176 template <class V>
1177 typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<0, allocate_dynamic>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
1178 {
1179 constexpr unsigned d10 = std::is_floating_point<V>::value ?
1180 std::numeric_limits<V>::digits10 :
1181 std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 :
1182 1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits);
1183
1184 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1185 {
1186 BOOST_IF_CONSTEXPR(std::is_floating_point<V>::value)
1187 {
1188 if (std::numeric_limits<V>::digits > mpfr_get_prec(this->data()))
1189 mpfr_set_prec(this->data(), std::numeric_limits<V>::digits);
1190 }
1191 else
1192 {
1193 if(precision() < d10)
1194 this->precision(d10);
1195 }
1196 }
1197
1198 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
1199 return *this;
1200 }
1201 mpfr_float_backend& operator=(const mpfr_t val)
1202 {
1203 if (this->m_data[0]._mpfr_d == nullptr)
1204 mpfr_init2(this->m_data, preserve_all_precision() ? static_cast<mpfr_prec_t>(mpfr_get_prec(val)) : static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision())));
1205 else if(preserve_all_precision())
1206 mpfr_set_prec(this->m_data, mpfr_get_prec(val));
1207 mpfr_set(this->m_data, val, GMP_RNDN);
1208 return *this;
1209 }
1210 mpfr_float_backend& operator=(const mpf_t val)
1211 {
1212 if (this->m_data[0]._mpfr_d == nullptr)
1213 mpfr_init2(this->m_data, preserve_all_precision() ? static_cast<mpfr_prec_t>(mpf_get_prec(val)) : static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision())));
1214 else if(preserve_all_precision())
1215 mpfr_set_prec(this->m_data, static_cast<mpfr_prec_t>(mpf_get_prec(val)));
1216 mpfr_set_f(this->m_data, val, GMP_RNDN);
1217 return *this;
1218 }
1219 mpfr_float_backend& operator=(const mpz_t val)
1220 {
1221 if (this->m_data[0]._mpfr_d == nullptr)
1222 mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(get_default_precision())));
1223 mpfr_set_z(this->m_data, val, GMP_RNDN);
1224 return *this;
1225 }
1226 mpfr_float_backend& operator=(const mpq_t val)
1227 {
1228 if (this->m_data[0]._mpfr_d == nullptr)
1229 mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(get_default_precision())));
1230 mpfr_set_q(this->m_data, val, GMP_RNDN);
1231 return *this;
1232 }
1233 template <unsigned D>
1234 mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
1235 {
1236 if (this->m_data[0]._mpfr_d == nullptr)
1237 mpfr_init2(this->m_data, preserve_related_precision() ? static_cast<mpfr_prec_t>(mpfr_get_prec(val.data())) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
1238 else if (preserve_related_precision())
1239 mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
1240 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1241 return *this;
1242 }
1243 template <unsigned D>
1244 mpfr_float_backend& operator=(const gmp_float<D>& val)
1245 {
1246 if (this->m_data[0]._mpfr_d == nullptr)
1247 mpfr_init2(this->m_data, preserve_all_precision() ? static_cast<mpfr_prec_t>(mpf_get_prec(val.data())) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
1248 else if (preserve_all_precision())
1249 mpfr_set_prec(this->m_data, static_cast<mpfr_prec_t>(mpf_get_prec(val.data())));
1250 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1251 return *this;
1252 }
1253 mpfr_float_backend& operator=(const gmp_int& val)
1254 {
1255 if (this->m_data[0]._mpfr_d == nullptr)
1256 {
1257 unsigned requested_precision = this->thread_default_precision();
1258 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1259 {
1260 unsigned d2 = static_cast<unsigned>(used_gmp_int_bits(val));
1261 unsigned d10 = static_cast<unsigned>(1ULL + multiprecision::detail::digits2_2_10(d2));
1262 if (d10 > requested_precision)
1263 requested_precision = d10;
1264 }
1265 mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(requested_precision)));
1266 }
1267 else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1268 {
1269 unsigned requested_precision = this->thread_default_precision();
1270 unsigned d2 = static_cast<unsigned>(used_gmp_int_bits(val));
1271 unsigned d10 = static_cast<unsigned>(1ULL + multiprecision::detail::digits2_2_10(d2));
1272 if (d10 > requested_precision)
1273 this->precision(d10);
1274 }
1275 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1276 return *this;
1277 }
1278 mpfr_float_backend& operator=(const gmp_rational& val)
1279 {
1280 if (this->m_data[0]._mpfr_d == nullptr)
1281 {
1282 unsigned requested_precision = this->get_default_precision();
1283 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1284 {
1285 unsigned d10 = static_cast<unsigned>(1u + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)));
1286 if (d10 > requested_precision)
1287 requested_precision = d10;
1288 }
1289 mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(requested_precision)));
1290 }
1291 else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1292 {
1293 unsigned requested_precision = this->get_default_precision();
1294 unsigned d10 = static_cast<unsigned>(1u + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)));
1295 if (d10 > requested_precision)
1296 this->precision(d10);
1297 }
1298 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1299 return *this;
1300 }
1301 static unsigned default_precision() noexcept
1302 {
1303 return get_global_default_precision();
1304 }
1305 static void default_precision(unsigned v) noexcept
1306 {
1307 get_global_default_precision() = v;
1308 }
1309 static unsigned thread_default_precision() noexcept
1310 {
1311 return get_default_precision();
1312 }
1313 static void thread_default_precision(unsigned v) noexcept
1314 {
1315 get_default_precision() = v;
1316 }
1317 unsigned precision() const noexcept
1318 {
1319 return static_cast<unsigned>(multiprecision::detail::digits2_2_10(static_cast<unsigned long>(mpfr_get_prec(this->m_data))));
1320 }
1321 void precision(unsigned digits10) noexcept
1322 {
1323 mpfr_prec_round(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2((digits10))), GMP_RNDN);
1324 }
1325
1326
1327
1328 static variable_precision_options default_variable_precision_options()noexcept
1329 {
1330 return get_global_default_options();
1331 }
1332 static variable_precision_options thread_default_variable_precision_options()noexcept
1333 {
1334 return get_default_options();
1335 }
1336 static void default_variable_precision_options(variable_precision_options opts)
1337 {
1338 get_global_default_options() = opts;
1339 }
1340 static void thread_default_variable_precision_options(variable_precision_options opts)
1341 {
1342 get_default_options() = opts;
1343 }
1344 static bool preserve_source_precision()
1345 {
1346 return get_default_options() >= variable_precision_options::preserve_source_precision;
1347 }
1348 static bool preserve_related_precision()
1349 {
1350 return get_default_options() >= variable_precision_options::preserve_related_precision;
1351 }
1352 static bool preserve_all_precision()
1353 {
1354 return get_default_options() >= variable_precision_options::preserve_all_precision;
1355 }
1356 };
1357
1358 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1359 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
1360 {
1361 return a.compare(b) == 0;
1362 }
1363 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1364 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
1365 {
1366 return a.compare(b) < 0;
1367 }
1368 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1369 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
1370 {
1371 return a.compare(b) > 0;
1372 }
1373
1374 template <unsigned digits10, mpfr_allocation_type AllocationType>
1375 inline bool eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b)noexcept
1376 {
1377 return mpfr_equal_p(a.data(), b.data());
1378 }
1379 template <unsigned digits10, mpfr_allocation_type AllocationType>
1380 inline bool eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
1381 {
1382 return mpfr_less_p(a.data(), b.data());
1383 }
1384 template <unsigned digits10, mpfr_allocation_type AllocationType>
1385 inline bool eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
1386 {
1387 return mpfr_greater_p(a.data(), b.data());
1388 }
1389
1390 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1391 inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1392 {
1393 mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
1394 }
1395 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1396 inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1397 {
1398 mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
1399 }
1400 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1401 inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1402 {
1403 if ((void*)&o == (void*)&result)
1404 mpfr_sqr(result.data(), o.data(), GMP_RNDN);
1405 else
1406 mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
1407 }
1408 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1409 inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1410 {
1411 mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
1412 }
1413 template <unsigned digits10, mpfr_allocation_type AllocationType>
1414 inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1415 {
1416 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1417 }
1418 template <unsigned digits10, mpfr_allocation_type AllocationType>
1419 inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1420 {
1421 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
1422 }
1423 template <unsigned digits10, mpfr_allocation_type AllocationType>
1424 inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1425 {
1426 mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
1427 }
1428 template <unsigned digits10, mpfr_allocation_type AllocationType>
1429 inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1430 {
1431 mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
1432 }
1433 template <unsigned digits10, mpfr_allocation_type AllocationType>
1434 inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
1435 {
1436 if (i > 0)
1437 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1438 else
1439 mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1440 }
1441 template <unsigned digits10, mpfr_allocation_type AllocationType>
1442 inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
1443 {
1444 if (i > 0)
1445 mpfr_sub_ui(result.data(), result.data(), static_cast<typename std::make_unsigned<long>::type>(i), GMP_RNDN);
1446 else
1447 mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1448 }
1449 template <unsigned digits10, mpfr_allocation_type AllocationType>
1450 inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
1451 {
1452 mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1453 if (i < 0)
1454 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1455 }
1456 template <unsigned digits10, mpfr_allocation_type AllocationType>
1457 inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
1458 {
1459 mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1460 if (i < 0)
1461 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1462 }
1463
1464
1465
1466 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1467 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
1468 {
1469 mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
1470 }
1471 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1472 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1473 {
1474 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1475 }
1476 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1477 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1478 {
1479 if (y < 0)
1480 mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1481 else
1482 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1483 }
1484 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1485 inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1486 {
1487 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1488 }
1489 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1490 inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1491 {
1492 if (x < 0)
1493 {
1494 mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1495 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1496 }
1497 else
1498 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1499 }
1500 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1501 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
1502 {
1503 mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
1504 }
1505 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1506 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1507 {
1508 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1509 }
1510 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1511 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1512 {
1513 if (y < 0)
1514 mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1515 else
1516 mpfr_sub_ui(a.data(), x.data(), static_cast<typename std::make_unsigned<long>::type>(y), GMP_RNDN);
1517 }
1518 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1519 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1520 {
1521 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1522 }
1523 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1524 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1525 {
1526 if (x < 0)
1527 {
1528 mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1529 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1530 }
1531 else
1532 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1533 }
1534
1535 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1536 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
1537 {
1538 if ((void*)&x == (void*)&y)
1539 mpfr_sqr(a.data(), x.data(), GMP_RNDN);
1540 else
1541 mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
1542 }
1543 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1544 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1545 {
1546 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1547 }
1548 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1549 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1550 {
1551 if (y < 0)
1552 {
1553 mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1554 a.negate();
1555 }
1556 else
1557 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1558 }
1559 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1560 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1561 {
1562 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1563 }
1564 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1565 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1566 {
1567 if (x < 0)
1568 {
1569 mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1570 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1571 }
1572 else
1573 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1574 }
1575
1576 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1577 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
1578 {
1579 mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
1580 }
1581 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1582 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1583 {
1584 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1585 }
1586 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1587 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1588 {
1589 if (y < 0)
1590 {
1591 mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1592 a.negate();
1593 }
1594 else
1595 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1596 }
1597 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1598 inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1599 {
1600 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1601 }
1602 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1603 inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1604 {
1605 if (x < 0)
1606 {
1607 mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1608 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1609 }
1610 else
1611 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1612 }
1613
1614 template <unsigned digits10, mpfr_allocation_type AllocationType>
1615 inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1616 {
1617 return 0 != mpfr_zero_p(val.data());
1618 }
1619 template <unsigned digits10, mpfr_allocation_type AllocationType>
1620 inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1621 {
1622 return mpfr_sgn(val.data());
1623 }
1624
1625 template <unsigned digits10, mpfr_allocation_type AllocationType>
1626 inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1627 {
1628 if (mpfr_nan_p(val.data()))
1629 {
1630 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1631 }
1632 *result = mpfr_get_ui(val.data(), GMP_RNDZ);
1633 }
1634 template <unsigned digits10, mpfr_allocation_type AllocationType>
1635 inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1636 {
1637 if (mpfr_nan_p(val.data()))
1638 {
1639 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1640 }
1641 *result = mpfr_get_si(val.data(), GMP_RNDZ);
1642 }
1643 #ifdef _MPFR_H_HAVE_INTMAX_T
1644 template <unsigned digits10, mpfr_allocation_type AllocationType>
1645 inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1646 {
1647 if (mpfr_nan_p(val.data()))
1648 {
1649 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1650 }
1651 *result = mpfr_get_uj(val.data(), GMP_RNDZ);
1652 }
1653 template <unsigned digits10, mpfr_allocation_type AllocationType>
1654 inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1655 {
1656 if (mpfr_nan_p(val.data()))
1657 {
1658 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1659 }
1660 *result = mpfr_get_sj(val.data(), GMP_RNDZ);
1661 }
1662 #endif
1663 template <unsigned digits10, mpfr_allocation_type AllocationType>
1664 inline void eval_convert_to(float* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1665 {
1666 *result = mpfr_get_flt(val.data(), GMP_RNDN);
1667 }
1668 template <unsigned digits10, mpfr_allocation_type AllocationType>
1669 inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1670 {
1671 *result = mpfr_get_d(val.data(), GMP_RNDN);
1672 }
1673 template <unsigned digits10, mpfr_allocation_type AllocationType>
1674 inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1675 {
1676 *result = mpfr_get_ld(val.data(), GMP_RNDN);
1677 }
1678
1679 #ifdef BOOST_HAS_INT128
1680 template <unsigned digits10, mpfr_allocation_type AllocationType>
1681 inline void eval_convert_to(int128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1682 {
1683 gmp_int i;
1684 mpfr_get_z(i.data(), val.data(), GMP_RNDN);
1685 eval_convert_to(result, i);
1686 }
1687 template <unsigned digits10, mpfr_allocation_type AllocationType>
1688 inline void eval_convert_to(uint128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1689 {
1690 gmp_int i;
1691 mpfr_get_z(i.data(), val.data(), GMP_RNDN);
1692 eval_convert_to(result, i);
1693 }
1694 #endif
1695 #if defined(BOOST_HAS_FLOAT128)
1696 template <unsigned digits10, mpfr_allocation_type AllocationType>
1697 inline void eval_convert_to(float128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1698 {
1699 *result = float128_procs::strtoflt128(val.str(0, std::ios_base::scientific).c_str(), nullptr);
1700 }
1701 #endif
1702
1703
1704
1705
1706 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1707 inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1708 {
1709 mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
1710 }
1711
1712 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1713 inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1714 {
1715 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1716 }
1717
1718 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1719 inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1720 {
1721 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1722 }
1723 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1724 inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1725 {
1726 mpfr_ceil(result.data(), val.data());
1727 }
1728 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1729 inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1730 {
1731 mpfr_floor(result.data(), val.data());
1732 }
1733 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1734 inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1735 {
1736 mpfr_trunc(result.data(), val.data());
1737 }
1738 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1739 inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
1740 {
1741 using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
1742
1743 if (e > 0)
1744 mpfr_mul_2exp(result.data(), val.data(), static_cast<local_uint_type>(e), GMP_RNDN);
1745 else if (e < 0)
1746 mpfr_div_2exp(result.data(), val.data(), static_cast<local_uint_type>(-e), GMP_RNDN);
1747 else
1748 result = val;
1749 }
1750 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1751 inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
1752 {
1753 if (mpfr_zero_p(val.data()))
1754 {
1755 *e = 0;
1756 result = val;
1757 return;
1758 }
1759 mp_exp_t v = mpfr_get_exp(val.data());
1760 *e = static_cast<int>(v);
1761 if (v)
1762 eval_ldexp(result, val, -v);
1763 else
1764 result = val;
1765 }
1766 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1767 inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
1768 {
1769 if (mpfr_zero_p(val.data()))
1770 {
1771 *e = 0;
1772 result = val;
1773 return;
1774 }
1775 mp_exp_t v = mpfr_get_exp(val.data());
1776 *e = v;
1777 if(v)
1778 eval_ldexp(result, val, -v);
1779 else
1780 result = val;
1781 }
1782
1783 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1784 inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) noexcept
1785 {
1786 return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
1787 }
1788
1789 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1790 inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
1791 {
1792 if (mpfr_zero_p(b.data()) && mpfr_integer_p(e.data()) && (mpfr_signbit(e.data()) == 0) && mpfr_fits_ulong_p(e.data(), GMP_RNDN) && (mpfr_get_ui(e.data(), GMP_RNDN) & 1))
1793 {
1794 mpfr_set(result.data(), b.data(), GMP_RNDN);
1795 }
1796 else
1797 mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1798 }
1799
1800 #ifdef BOOST_MSVC
1801
1802
1803
1804
1805
1806 #define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10)&&
1807 #else
1808 #define BOOST_MP_ENABLE_IF_WORKAROUND
1809 #endif
1810
1811 template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1812 inline typename std::enable_if<boost::multiprecision::detail::is_signed<Integer>::value && boost::multiprecision::detail::is_integral<Integer>::value && (BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long)))>::type
1813 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
1814 {
1815 mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
1816 }
1817
1818 template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1819 inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value && (BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long)))>::type
1820 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
1821 {
1822 mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
1823 }
1824
1825 #undef BOOST_MP_ENABLE_IF_WORKAROUND
1826
1827 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1828 inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1829 {
1830 mpfr_exp(result.data(), arg.data(), GMP_RNDN);
1831 }
1832
1833 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1834 inline void eval_exp2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1835 {
1836 mpfr_exp2(result.data(), arg.data(), GMP_RNDN);
1837 }
1838
1839 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1840 inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1841 {
1842 mpfr_log(result.data(), arg.data(), GMP_RNDN);
1843 }
1844
1845 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1846 inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1847 {
1848 mpfr_log10(result.data(), arg.data(), GMP_RNDN);
1849 }
1850
1851 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1852 inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1853 {
1854 mpfr_sin(result.data(), arg.data(), GMP_RNDN);
1855 }
1856
1857 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1858 inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1859 {
1860 mpfr_cos(result.data(), arg.data(), GMP_RNDN);
1861 }
1862
1863 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1864 inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1865 {
1866 mpfr_tan(result.data(), arg.data(), GMP_RNDN);
1867 }
1868
1869 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1870 inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1871 {
1872 mpfr_asin(result.data(), arg.data(), GMP_RNDN);
1873 }
1874
1875 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1876 inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1877 {
1878 mpfr_acos(result.data(), arg.data(), GMP_RNDN);
1879 }
1880
1881 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1882 inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1883 {
1884 mpfr_atan(result.data(), arg.data(), GMP_RNDN);
1885 }
1886
1887 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1888 inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
1889 {
1890 mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
1891 }
1892
1893 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1894 inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1895 {
1896 mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
1897 }
1898
1899 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1900 inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1901 {
1902 mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
1903 }
1904
1905 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1906 inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1907 {
1908 mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
1909 }
1910
1911 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1912 inline void eval_log2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1913 {
1914 mpfr_log2(result.data(), arg.data(), GMP_RNDN);
1915 }
1916
1917 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1918 inline void eval_modf(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg, mpfr_float_backend<Digits10, AllocateType>* pipart)
1919 {
1920 if (pipart == nullptr)
1921 {
1922 mpfr_float_backend<Digits10, AllocateType> ipart;
1923 mpfr_modf(ipart.data(), result.data(), arg.data(), GMP_RNDN);
1924 }
1925 else
1926 {
1927 mpfr_modf(pipart->data(), result.data(), arg.data(), GMP_RNDN);
1928 }
1929 }
1930 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1931 inline void eval_remainder(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1932 {
1933 mpfr_remainder(result.data(), a.data(), b.data(), GMP_RNDN);
1934 }
1935 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1936 inline void eval_remquo(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, int* pi)
1937 {
1938 long l;
1939 mpfr_remquo(result.data(), &l, a.data(), b.data(), GMP_RNDN);
1940 if (pi)
1941 *pi = static_cast<int>(l);
1942 }
1943
1944 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1945 inline void eval_fmod(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1946 {
1947 mpfr_fmod(result.data(), a.data(), b.data(), GMP_RNDN);
1948 }
1949
1950 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1951 inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1952 {
1953 mpfr_fma(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1954 }
1955
1956 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1957 inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
1958 {
1959 mpfr_fma(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1960 }
1961
1962 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1963 inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1964 {
1965 mpfr_fms(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1966 result.negate();
1967 }
1968
1969 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1970 inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
1971 {
1972 mpfr_fms(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1973 }
1974
1975 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1976 inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const mpfr_float_backend<Digits10, AllocateType>& arg)
1977 {
1978 return (arg.data()[0]._mpfr_sign < 0) ? 1 : 0;
1979 }
1980
1981 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1982 inline std::size_t hash_value(const mpfr_float_backend<Digits10, AllocateType>& val)
1983 {
1984 std::size_t result = 0;
1985 std::size_t len = val.data()[0]._mpfr_prec / mp_bits_per_limb;
1986 if (val.data()[0]._mpfr_prec % mp_bits_per_limb)
1987 ++len;
1988 for (std::size_t i = 0; i < len; ++i)
1989 boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_d[i]);
1990 boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_exp, val.data()[0]._mpfr_sign);
1991 return result;
1992 }
1993
1994 }
1995
1996 namespace detail {
1997 template <>
1998 struct is_variable_precision<backends::mpfr_float_backend<0> > : public std::integral_constant<bool, true>
1999 {};
2000 }
2001
2002 template <>
2003 struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public std::integral_constant<int, number_kind_floating_point>
2004 {};
2005
2006 template <unsigned D, boost::multiprecision::mpfr_allocation_type A1, boost::multiprecision::mpfr_allocation_type A2>
2007 struct is_equivalent_number_type<backends::mpfr_float_backend<D, A1>, backends::mpfr_float_backend<D, A2> > : public std::integral_constant<bool, true> {};
2008
2009 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2010 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& b)
2011 {
2012 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(-a) : a;
2013 }
2014
2015 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2016 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& b)
2017 {
2018 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>(-a) : a;
2019 }
2020
2021 }
2022
2023 namespace math {
2024
2025 using boost::multiprecision::copysign;
2026 using boost::multiprecision::signbit;
2027
2028 namespace tools {
2029
2030 #ifndef BOOST_MP_MATH_AVAILABLE
2031
2032 template <typename T>
2033 inline int digits();
2034
2035 template <typename T>
2036 inline T max_value();
2037
2038 template <typename T>
2039 inline T min_value();
2040
2041 #endif
2042
2043 inline void set_output_precision(const boost::multiprecision::mpfr_float& val, std::ostream& os)
2044 {
2045 os << std::setprecision(static_cast<int>(val.precision()));
2046 }
2047
2048 template <>
2049 inline int digits<boost::multiprecision::mpfr_float>()
2050 #ifdef BOOST_MATH_NOEXCEPT
2051 noexcept
2052 #endif
2053 {
2054 return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision()));
2055 }
2056 template <>
2057 inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
2058 #ifdef BOOST_MATH_NOEXCEPT
2059 noexcept
2060 #endif
2061 {
2062 return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision()));
2063 }
2064
2065 template <>
2066 inline boost::multiprecision::mpfr_float
2067 max_value<boost::multiprecision::mpfr_float>()
2068 {
2069 boost::multiprecision::mpfr_float result(0.5);
2070 mpfr_mul_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(mpfr_get_emax()), GMP_RNDN);
2071 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
2072 return result;
2073 }
2074
2075 template <>
2076 inline boost::multiprecision::mpfr_float
2077 min_value<boost::multiprecision::mpfr_float>()
2078 {
2079 boost::multiprecision::mpfr_float result(0.5);
2080 mpfr_div_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(-mpfr_get_emin()), GMP_RNDN);
2081 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
2082 return result;
2083 }
2084
2085 template <>
2086 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
2087 max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
2088 {
2089 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
2090 mpfr_mul_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(mpfr_get_emax()), GMP_RNDN);
2091 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
2092 return result;
2093 }
2094
2095 template <>
2096 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
2097 min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
2098 {
2099 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
2100 mpfr_div_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(-mpfr_get_emin()), GMP_RNDN);
2101 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
2102 return result;
2103 }
2104
2105
2106
2107 template <>
2108 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2109 #ifdef BOOST_MATH_NOEXCEPT
2110 noexcept
2111 #endif
2112 {
2113 return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::thread_default_precision()));
2114 }
2115 template <>
2116 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2117 #ifdef BOOST_MATH_NOEXCEPT
2118 noexcept
2119 #endif
2120 {
2121 return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::thread_default_precision()));
2122 }
2123
2124 template <>
2125 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2126 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2127 {
2128 return max_value<boost::multiprecision::mpfr_float>().backend();
2129 }
2130
2131 template <>
2132 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2133 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2134 {
2135 return min_value<boost::multiprecision::mpfr_float>().backend();
2136 }
2137
2138 template <>
2139 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2140 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2141 {
2142 return max_value<boost::multiprecision::mpfr_float>().backend();
2143 }
2144
2145 template <>
2146 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2147 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2148 {
2149 return min_value<boost::multiprecision::mpfr_float>().backend();
2150 }
2151
2152
2153
2154
2155 template <>
2156 inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2157 #ifdef BOOST_MATH_NOEXCEPT
2158 noexcept
2159 #endif
2160 {
2161 return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision()));
2162 }
2163 template <>
2164 inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2165 #ifdef BOOST_MATH_NOEXCEPT
2166 noexcept
2167 #endif
2168 {
2169 return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision()));
2170 }
2171
2172 template <>
2173 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2174 max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2175 {
2176 return max_value<boost::multiprecision::mpfr_float>().backend();
2177 }
2178
2179 template <>
2180 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2181 min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2182 {
2183 return min_value<boost::multiprecision::mpfr_float>().backend();
2184 }
2185
2186 template <>
2187 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2188 max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2189 {
2190 return max_value<boost::multiprecision::mpfr_float>().backend();
2191 }
2192
2193 template <>
2194 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2195 min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2196 {
2197 return min_value<boost::multiprecision::mpfr_float>().backend();
2198 }
2199
2200 }
2201
2202 namespace constants { namespace detail {
2203
2204 template <class T>
2205 struct constant_pi;
2206 template <class T>
2207 struct constant_ln_two;
2208 template <class T>
2209 struct constant_euler;
2210 template <class T>
2211 struct constant_catalan;
2212
2213 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2214 struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2215 {
2216 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
2217 template <int N>
2218 static inline const result_type& get(const std::integral_constant<int, N>&)
2219 {
2220
2221 static result_type result{get(std::integral_constant<int, 0>())};
2222 return result;
2223 }
2224 static inline const result_type get(const std::integral_constant<int, 0>&)
2225 {
2226 result_type result;
2227 mpfr_const_pi(result.backend().data(), GMP_RNDN);
2228 return result;
2229 }
2230 };
2231 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2232 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2233 {
2234 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
2235 template <int N>
2236 static inline const result_type& get(const std::integral_constant<int, N>&)
2237 {
2238
2239 static result_type result{get(std::integral_constant<int, 0>())};
2240 return result;
2241 }
2242 static inline const result_type get(const std::integral_constant<int, 0>&)
2243 {
2244 result_type result;
2245 mpfr_const_log2(result.backend().data(), GMP_RNDN);
2246 return result;
2247 }
2248 };
2249 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2250 struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2251 {
2252 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
2253 template <int N>
2254 static inline const result_type& get(const std::integral_constant<int, N>&)
2255 {
2256
2257 static result_type result{get(std::integral_constant<int, 0>())};
2258 return result;
2259 }
2260 static inline const result_type get(const std::integral_constant<int, 0>&)
2261 {
2262 result_type result;
2263 mpfr_const_euler(result.backend().data(), GMP_RNDN);
2264 return result;
2265 }
2266 };
2267 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2268 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2269 {
2270 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
2271 template <int N>
2272 static inline const result_type& get(const std::integral_constant<int, N>&)
2273 {
2274
2275 static result_type result{get(std::integral_constant<int, 0>())};
2276 return result;
2277 }
2278 static inline const result_type get(const std::integral_constant<int, 0>&)
2279 {
2280 result_type result;
2281 mpfr_const_catalan(result.backend().data(), GMP_RNDN);
2282 return result;
2283 }
2284 };
2285
2286
2287
2288 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2289 struct constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2290 {
2291 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2292 template <int N>
2293 static inline const result_type& get(const std::integral_constant<int, N>&)
2294 {
2295
2296 static result_type result{get(std::integral_constant<int, 0>())};
2297 return result;
2298 }
2299 static inline const result_type get(const std::integral_constant<int, 0>&)
2300 {
2301 result_type result;
2302 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
2303 result.backend().update_view();
2304 return result;
2305 }
2306 };
2307 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2308 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2309 {
2310 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2311 template <int N>
2312 static inline const result_type& get(const std::integral_constant<int, N>&)
2313 {
2314
2315 static result_type result{get(std::integral_constant<int, 0>())};
2316 return result;
2317 }
2318 static inline const result_type get(const std::integral_constant<int, 0>&)
2319 {
2320 result_type result;
2321 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
2322 result.backend().update_view();
2323 return result;
2324 }
2325 };
2326 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2327 struct constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2328 {
2329 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2330 template <int N>
2331 static inline const result_type& get(const std::integral_constant<int, N>&)
2332 {
2333
2334 static result_type result{get(std::integral_constant<int, 0>())};
2335 return result;
2336 }
2337 static inline const result_type get(const std::integral_constant<int, 0>&)
2338 {
2339 result_type result;
2340 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
2341 result.backend().update_view();
2342 return result;
2343 }
2344 };
2345 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2346 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2347 {
2348 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2349 template <int N>
2350 static inline const result_type& get(const std::integral_constant<int, N>&)
2351 {
2352
2353 static result_type result{get(std::integral_constant<int, 0>())};
2354 return result;
2355 }
2356 static inline const result_type get(const std::integral_constant<int, 0>&)
2357 {
2358 result_type result;
2359 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
2360 result.backend().update_view();
2361 return result;
2362 }
2363 };
2364
2365
2366
2367
2368 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2369 struct constant_pi<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2370 {
2371 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2372 template <int N>
2373 static inline const result_type& get(const std::integral_constant<int, N>&)
2374 {
2375
2376 static result_type result{get(std::integral_constant<int, 0>())};
2377 return result;
2378 }
2379 static inline const result_type get(const std::integral_constant<int, 0>&)
2380 {
2381 result_type result;
2382 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
2383 return result;
2384 }
2385 };
2386 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2387 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2388 {
2389 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2390 template <int N>
2391 static inline const result_type& get(const std::integral_constant<int, N>&)
2392 {
2393
2394 static result_type result{get(std::integral_constant<int, 0>())};
2395 return result;
2396 }
2397 static inline const result_type get(const std::integral_constant<int, 0>&)
2398 {
2399 result_type result;
2400 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
2401 return result;
2402 }
2403 };
2404 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2405 struct constant_euler<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2406 {
2407 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2408 template <int N>
2409 static inline const result_type& get(const std::integral_constant<int, N>&)
2410 {
2411
2412 static result_type result{get(std::integral_constant<int, 0>())};
2413 return result;
2414 }
2415 static inline const result_type get(const std::integral_constant<int, 0>&)
2416 {
2417 result_type result;
2418 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
2419 return result;
2420 }
2421 };
2422 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2423 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2424 {
2425 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2426 template <int N>
2427 static inline const result_type& get(const std::integral_constant<int, N>&)
2428 {
2429
2430 static result_type result{get(std::integral_constant<int, 0>())};
2431 return result;
2432 }
2433 static inline const result_type get(const std::integral_constant<int, 0>&)
2434 {
2435 result_type result;
2436 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
2437 return result;
2438 }
2439 };
2440
2441 }}
2442
2443 }
2444
2445 namespace multiprecision {
2446
2447
2448
2449 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2450 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2451 {
2452 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2453
2454 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2455 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2456 return result;
2457 }
2458 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2459 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2460 {
2461 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2462
2463 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2464 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2465 return result;
2466 }
2467 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2468 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2469 {
2470 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2471
2472 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2473 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2474 return result;
2475 }
2476 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2477 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2478 {
2479 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2480
2481 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2482 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2483 return result;
2484 }
2485 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2486 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2487 {
2488 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2489
2490 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2491 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
2492 return result;
2493 }
2494 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2495 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2496 {
2497 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2498
2499 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2500 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
2501 return result;
2502 }
2503 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2504 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2505 {
2506 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2507
2508 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2509 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
2510 return result;
2511 }
2512 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2513 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2514 {
2515 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2516
2517 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2518 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2519 return result;
2520 }
2521 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2522 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2523 {
2524 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2525
2526 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2527 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2528 return result;
2529 }
2530 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2531 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2532 {
2533 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2534
2535 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2536 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
2537 return result;
2538 }
2539
2540
2541
2542
2543 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2544 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2545 {
2546 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2547
2548 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2549 mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2550 result.backend().update_view();
2551 return result;
2552 }
2553 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2554 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2555 {
2556 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2557
2558 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2559 mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2560 result.backend().update_view();
2561 return result;
2562 }
2563 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2564 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2565 {
2566 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2567
2568 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2569 mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2570 result.backend().update_view();
2571 return result;
2572 }
2573 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2574 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2575 {
2576 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2577
2578 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2579 mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2580 result.backend().update_view();
2581 return result;
2582 }
2583 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2584 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2585 {
2586 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2587
2588 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2589 mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2590 result.backend().update_view();
2591 return result;
2592 }
2593 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2594 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2595 {
2596 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2597
2598 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2599 mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2600 result.backend().update_view();
2601 return result;
2602 }
2603 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2604 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2605 {
2606 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2607
2608 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2609 mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2610 result.backend().update_view();
2611 return result;
2612 }
2613 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2614 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2615 {
2616 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2617
2618 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2619 mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2620 result.backend().update_view();
2621 return result;
2622 }
2623 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2624 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2625 {
2626 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2627
2628 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2629 mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2630 result.backend().update_view();
2631 return result;
2632 }
2633 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2634 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2635 {
2636 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2637
2638 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2639 mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2640 result.backend().update_view();
2641 return result;
2642 }
2643
2644
2645
2646
2647 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2648 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2649 {
2650 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2651
2652 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2653 mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2654 return result;
2655 }
2656 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2657 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2658 {
2659 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2660
2661 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2662 mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2663 return result;
2664 }
2665 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2666 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2667 {
2668 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2669
2670 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2671 mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2672 return result;
2673 }
2674 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2675 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2676 {
2677 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2678
2679 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2680 mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2681 return result;
2682 }
2683 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2684 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2685 {
2686 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2687
2688 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2689 mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2690 return result;
2691 }
2692 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2693 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2694 {
2695 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2696
2697 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2698 mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2699 return result;
2700 }
2701 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2702 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2703 {
2704 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2705
2706 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2707 mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2708 return result;
2709 }
2710 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2711 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2712 {
2713 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2714
2715 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2716 mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2717 return result;
2718 }
2719 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2720 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2721 {
2722 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2723
2724 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2725 mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2726 return result;
2727 }
2728 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2729 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2730 {
2731 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2732
2733 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2734 mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2735 return result;
2736 }
2737
2738 }
2739
2740 namespace math {
2741
2742
2743
2744 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2745 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2746 {
2747 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2748
2749 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2750 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2751 if (mpfr_inf_p(result.backend().data()))
2752 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("asinh<%1%>(%1%)", nullptr, Policy());
2753 if (mpfr_nan_p(result.backend().data()))
2754 return policies::raise_evaluation_error("asinh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2755 return result;
2756 }
2757 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2758 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2759 {
2760 return asinh(arg, policies::policy<>());
2761 }
2762
2763 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2764 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2765 {
2766 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2767
2768 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2769 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2770 if (mpfr_inf_p(result.backend().data()))
2771 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("acosh<%1%>(%1%)", nullptr, Policy());
2772 if (mpfr_nan_p(result.backend().data()))
2773 return policies::raise_evaluation_error("acosh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2774 return result;
2775 }
2776 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2777 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2778 {
2779 return acosh(arg, policies::policy<>());
2780 }
2781
2782 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2783 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& )
2784 {
2785 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2786
2787 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2788 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2789 if (mpfr_inf_p(result.backend().data()))
2790 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("atanh<%1%>(%1%)", nullptr, Policy());
2791 if (mpfr_nan_p(result.backend().data()))
2792 return policies::raise_evaluation_error("atanh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2793 return result;
2794 }
2795 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2796 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2797 {
2798 return atanh(arg, policies::policy<>());
2799 }
2800
2801 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2802 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2803 {
2804 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2805
2806 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2807 if (mpfr_nan_p(arg.backend().data()))
2808 return policies::raise_domain_error("cbrt<%1%>(%1%)", "Input is a NaN", result, Policy());
2809 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2810 if (mpfr_inf_p(result.backend().data()))
2811 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("cbrt<%1%>(%1%)", nullptr, Policy());
2812 if (mpfr_nan_p(result.backend().data()))
2813 return policies::raise_evaluation_error("cbrt<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2814 return result;
2815 }
2816 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2817 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2818 {
2819 return cbrt(arg, policies::policy<>());
2820 }
2821
2822 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2823 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2824 {
2825 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2826
2827 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2828 if (mpfr_nan_p(arg.backend().data()))
2829 return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
2830 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
2831 if (mpfr_inf_p(result.backend().data()))
2832 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erf<%1%>(%1%)", nullptr, pol);
2833 if (mpfr_nan_p(result.backend().data()))
2834 return policies::raise_evaluation_error("erf<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2835 return result;
2836 }
2837 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2838 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2839 {
2840 return erf(arg, policies::policy<>());
2841 }
2842
2843 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2844 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2845 {
2846 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2847
2848 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2849 if (mpfr_nan_p(arg.backend().data()))
2850 return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
2851 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
2852 if (mpfr_inf_p(result.backend().data()))
2853 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erfc<%1%>(%1%)", nullptr, pol);
2854 if (mpfr_nan_p(result.backend().data()))
2855 return policies::raise_evaluation_error("erfc<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2856 return result;
2857 }
2858 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2859 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2860 {
2861 return erfc(arg, policies::policy<>());
2862 }
2863
2864 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2865 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2866 {
2867 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2868
2869 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2870 if (mpfr_nan_p(arg.backend().data()))
2871 return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
2872 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
2873 if (mpfr_inf_p(result.backend().data()))
2874 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("expm1<%1%>(%1%)", nullptr, pol);
2875 if (mpfr_nan_p(result.backend().data()))
2876 return policies::raise_evaluation_error("expm1<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2877 return result;
2878 }
2879 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2880 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2881 {
2882 return expm1(arg, policies::policy<>());
2883 }
2884
2885 #ifdef BOOST_MP_MATH_AVAILABLE
2886 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2887 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> arg, int* sign, const Policy& pol)
2888 {
2889 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2890 (void)precision_guard;
2891
2892 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2893 if (arg > 0)
2894 {
2895 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2896 if (sign)
2897 *sign = 1;
2898 }
2899 else
2900 {
2901 if (floor(arg) == arg)
2902 return policies::raise_pole_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >(
2903 "lgamma<%1%>", "Evaluation of lgamma at a negative integer %1%.", arg, pol);
2904
2905 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> t = detail::sinpx(arg);
2906 arg = -arg;
2907 if (t < 0)
2908 {
2909 t = -t;
2910 }
2911 result = boost::multiprecision::log(boost::math::constants::pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >()) - lgamma(arg, 0, pol) - boost::multiprecision::log(t);
2912 if (sign)
2913 {
2914 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> phase = 1 - arg;
2915 phase = floor(phase) / 2;
2916 if (floor(phase) == phase)
2917 *sign = -1;
2918 else
2919 *sign = 1;
2920 }
2921 }
2922 if (mpfr_inf_p(result.backend().data()))
2923 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("lgamma<%1%>(%1%)", nullptr, pol);
2924 if (mpfr_nan_p(result.backend().data()))
2925 return policies::raise_evaluation_error("lgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2926 return result;
2927 }
2928 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2929 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, int* sign)
2930 {
2931 return lgamma(arg, sign, policies::policy<>());
2932 }
2933 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2934 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2935 {
2936 return lgamma(arg, 0, pol);
2937 }
2938 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2939 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2940 {
2941 return lgamma(arg, 0, policies::policy<>());
2942 }
2943 #endif
2944
2945 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2946 inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2947 {
2948 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2949
2950 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2951 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2952 if (mpfr_inf_p(result.backend().data()))
2953 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("tgamma<%1%>(%1%)", nullptr, pol);
2954 if (mpfr_nan_p(result.backend().data()))
2955 return policies::raise_evaluation_error("tgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2956 return result;
2957 }
2958 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2959 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2960 {
2961 return tgamma(arg, policies::policy<>());
2962 }
2963
2964 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2965 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2966 {
2967 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2968
2969 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2970 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
2971 if (mpfr_inf_p(result.backend().data()))
2972 return (arg == -1 ? -1 : 1) * policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("log1p<%1%>(%1%)", nullptr, pol);
2973 if (mpfr_nan_p(result.backend().data()))
2974 return policies::raise_evaluation_error("log1p<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2975 return result;
2976 }
2977 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2978 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2979 {
2980 return log1p(arg, policies::policy<>());
2981 }
2982
2983 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2984 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2985 {
2986 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2987
2988 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2989 mpfr_rec_sqrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2990 if (mpfr_inf_p(result.backend().data()))
2991 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("rsqrt<%1%>(%1%)", nullptr, pol);
2992 if (mpfr_nan_p(result.backend().data()))
2993 return policies::raise_evaluation_error("rsqrt<%1%>(%1%)", "Negative argument, result is a NaN", result, pol);
2994 return result;
2995 }
2996 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2997 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2998 {
2999 return rsqrt(arg, policies::policy<>());
3000 }
3001
3002
3003
3004
3005 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3006 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3007 {
3008 return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3009 }
3010 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3011 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3012 {
3013 return asinh(arg, policies::policy<>());
3014 }
3015
3016 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3017 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3018 {
3019 return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3020 }
3021 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3022 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3023 {
3024 return acosh(arg, policies::policy<>());
3025 }
3026
3027 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3028 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3029 {
3030 return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3031 }
3032 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3033 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3034 {
3035 return atanh(arg, policies::policy<>());
3036 }
3037
3038 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3039 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3040 {
3041 return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3042 }
3043 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3044 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3045 {
3046 return cbrt(arg, policies::policy<>());
3047 }
3048
3049 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3050 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3051 {
3052 return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3053 }
3054 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3055 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3056 {
3057 return erf(arg, policies::policy<>());
3058 }
3059
3060 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3061 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3062 {
3063 return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3064 }
3065 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3066 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3067 {
3068 return erfc(arg, policies::policy<>());
3069 }
3070
3071 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3072 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3073 {
3074 return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3075 }
3076 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3077 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3078 {
3079 return expm1(arg, policies::policy<>());
3080 }
3081
3082 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3083 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> arg, int* sign, const Policy& pol)
3084 {
3085 return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
3086 }
3087 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3088 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, int* sign)
3089 {
3090 return lgamma(arg, sign, policies::policy<>());
3091 }
3092 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3093 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3094 {
3095 return lgamma(arg, 0, pol);
3096 }
3097 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3098 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3099 {
3100 return lgamma(arg, 0, policies::policy<>());
3101 }
3102
3103 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3104 inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3105 {
3106 return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3107 }
3108 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3109 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3110 {
3111 return tgamma(arg, policies::policy<>());
3112 }
3113
3114 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3115 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3116 {
3117 return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3118 }
3119 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3120 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3121 {
3122 return log1p(arg, policies::policy<>());
3123 }
3124
3125 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3126 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3127 {
3128 return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3129 }
3130 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3131 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3132 {
3133 return rsqrt(arg, policies::policy<>());
3134 }
3135
3136
3137
3138
3139 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3140 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3141 {
3142 return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3143 }
3144 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3145 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3146 {
3147 return asinh(arg, policies::policy<>());
3148 }
3149
3150 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3151 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3152 {
3153 return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3154 }
3155 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3156 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3157 {
3158 return acosh(arg, policies::policy<>());
3159 }
3160
3161 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3162 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3163 {
3164 return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3165 }
3166 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3167 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3168 {
3169 return atanh(arg, policies::policy<>());
3170 }
3171
3172 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3173 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3174 {
3175 return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3176 }
3177 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3178 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3179 {
3180 return cbrt(arg, policies::policy<>());
3181 }
3182
3183 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3184 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3185 {
3186 return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3187 }
3188 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3189 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3190 {
3191 return erf(arg, policies::policy<>());
3192 }
3193
3194 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3195 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3196 {
3197 return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3198 }
3199 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3200 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3201 {
3202 return erfc(arg, policies::policy<>());
3203 }
3204
3205 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3206 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3207 {
3208 return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3209 }
3210 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3211 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3212 {
3213 return expm1(arg, policies::policy<>());
3214 }
3215
3216 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3217 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> arg, int* sign, const Policy& pol)
3218 {
3219 return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
3220 }
3221 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3222 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, int* sign)
3223 {
3224 return lgamma(arg, sign, policies::policy<>());
3225 }
3226 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3227 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3228 {
3229 return lgamma(arg, 0, pol);
3230 }
3231 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3232 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3233 {
3234 return lgamma(arg, 0, policies::policy<>());
3235 }
3236
3237 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3238 inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3239 {
3240 return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3241 }
3242 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3243 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3244 {
3245 return tgamma(arg, policies::policy<>());
3246 }
3247
3248 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3249 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3250 {
3251 return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3252 }
3253 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3254 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3255 {
3256 return log1p(arg, policies::policy<>());
3257 }
3258
3259 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3260 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3261 {
3262 return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3263 }
3264 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3265 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3266 {
3267 return rsqrt(arg, policies::policy<>());
3268 }
3269
3270 }
3271
3272 }
3273
3274 namespace Eigen
3275 {
3276
3277 template <class B1, class B2>
3278 struct NumTraitsImp;
3279
3280 template <boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3281 struct NumTraitsImp<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>
3282 {
3283 using self_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>;
3284 using Real = typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type;
3285 using NonInteger = self_type;
3286 using Literal = double;
3287 using Nested = self_type;
3288 enum
3289 {
3290 IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
3291 IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
3292 ReadCost = 1,
3293 AddCost = 4,
3294 MulCost = 8,
3295 IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
3296 RequireInitialization = 1,
3297 };
3298 static Real epsilon()
3299 {
3300 #ifdef BOOST_MP_MATH_AVAILABLE
3301 return boost::math::tools::epsilon< boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3302 #else
3303 self_type result{1};
3304 mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<self_type>::digits - 1, GMP_RNDN);
3305 return result;
3306 #endif
3307 }
3308 static Real dummy_precision()
3309 {
3310 return 1000 * epsilon();
3311 }
3312 static Real highest()
3313 {
3314 #ifdef BOOST_MP_MATH_AVAILABLE
3315 return boost::math::tools::max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3316 #else
3317 self_type value(0.5);
3318 mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
3319 return value;
3320 #endif
3321 }
3322 static Real lowest()
3323 {
3324 #ifdef BOOST_MP_MATH_AVAILABLE
3325 return boost::math::tools::min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3326 #else
3327 return -(highest)();
3328 #endif
3329 }
3330 static int digits10()
3331 {
3332 return Real::thread_default_precision();
3333 }
3334 static int digits()
3335 {
3336 return boost::math::tools::digits<Real>();
3337 }
3338 static int min_exponent()
3339 {
3340 return static_cast<int>(mpfr_get_emin());
3341 }
3342 static int max_exponent()
3343 {
3344 return static_cast<int>(mpfr_get_emax());
3345 }
3346 static Real infinity()
3347 {
3348 return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::infinity();
3349 }
3350 static Real quiet_NaN()
3351 {
3352 return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::quiet_NaN();
3353 }
3354 };
3355
3356 }
3357
3358 namespace std {
3359
3360
3361
3362
3363 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3364 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
3365 {
3366 using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
3367
3368 static number_type get_min()
3369 {
3370 number_type result{0.5};
3371 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
3372 return result;
3373 }
3374 static number_type get_max()
3375 {
3376 number_type result{0.5};
3377 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
3378 return result;
3379 }
3380 static number_type get_eps()
3381 {
3382 number_type result{1};
3383 mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
3384 return result;
3385 }
3386
3387 public:
3388 static constexpr bool is_specialized = true;
3389 static number_type(min)()
3390 {
3391 static number_type value{get_min()};
3392 return value;
3393 }
3394 static number_type(max)()
3395 {
3396 static number_type value{get_max()};
3397 return value;
3398 }
3399 static constexpr number_type lowest()
3400 {
3401 return -(max)();
3402 }
3403 static constexpr int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
3404 static constexpr int digits10 = Digits10;
3405
3406 static constexpr int max_digits10 = static_cast<int>(boost::multiprecision::detail::calc_max_digits10<static_cast<unsigned>(digits)>::value);
3407 static constexpr bool is_signed = true;
3408 static constexpr bool is_integer = false;
3409 static constexpr bool is_exact = false;
3410 static constexpr int radix = 2;
3411 static number_type epsilon()
3412 {
3413 static number_type value{get_eps()};
3414 return value;
3415 }
3416
3417 static number_type round_error()
3418 {
3419
3420 return 0.5;
3421 }
3422 static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
3423 static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
3424 static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
3425 static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
3426 static constexpr bool has_infinity = true;
3427 static constexpr bool has_quiet_NaN = true;
3428 static constexpr bool has_signaling_NaN = false;
3429 #ifdef _MSC_VER
3430 #pragma warning(push)
3431 #pragma warning(disable : 4996)
3432 #endif
3433 static constexpr float_denorm_style has_denorm = denorm_absent;
3434 #ifdef _MSC_VER
3435 #pragma warning(pop)
3436 #endif
3437 static constexpr bool has_denorm_loss = false;
3438 static number_type infinity()
3439 {
3440 number_type value;
3441 mpfr_set_inf(value.backend().data(), 1);
3442 return value;
3443 }
3444 static number_type quiet_NaN()
3445 {
3446 number_type value;
3447 mpfr_set_nan(value.backend().data());
3448 return value;
3449 }
3450 static constexpr number_type signaling_NaN()
3451 {
3452 return number_type(0);
3453 }
3454 static constexpr number_type denorm_min() { return (min)(); }
3455 static constexpr bool is_iec559 = false;
3456 static constexpr bool is_bounded = true;
3457 static constexpr bool is_modulo = false;
3458 static constexpr bool traps = true;
3459 static constexpr bool tinyness_before = false;
3460 static constexpr float_round_style round_style = round_to_nearest;
3461 };
3462
3463 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3464 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
3465 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3466 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
3467 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3468 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
3469 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3470 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
3471 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3472 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
3473 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3474 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
3475 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3476 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
3477 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3478 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
3479 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3480 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
3481 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3482 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
3483 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3484 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
3485 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3486 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
3487 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3488 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
3489 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3490 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
3491 #ifdef _MSC_VER
3492 #pragma warning(push)
3493 #pragma warning(disable : 4996)
3494 #endif
3495 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3496 constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
3497 #ifdef _MSC_VER
3498 #pragma warning(pop)
3499 #endif
3500 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3501 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
3502 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3503 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
3504 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3505 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
3506 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3507 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
3508 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3509 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
3510 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3511 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
3512 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3513 constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
3514
3515 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3516 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
3517 {
3518 using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates>;
3519
3520 public:
3521 static constexpr bool is_specialized = false;
3522 static number_type(min)()
3523 {
3524 number_type value(0.5);
3525 mpfr_div_2exp(value.backend().data(), value.backend().data(), -mpfr_get_emin(), GMP_RNDN);
3526 return value;
3527 }
3528 static number_type(max)()
3529 {
3530 number_type value(0.5);
3531 mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
3532 return value;
3533 }
3534 static number_type lowest()
3535 {
3536 return -(max)();
3537 }
3538 static constexpr int digits = INT_MAX;
3539 static constexpr int digits10 = INT_MAX;
3540 static constexpr int max_digits10 = INT_MAX;
3541 static constexpr bool is_signed = true;
3542 static constexpr bool is_integer = false;
3543 static constexpr bool is_exact = false;
3544 static constexpr int radix = 2;
3545 static number_type epsilon()
3546 {
3547 number_type value(1);
3548 mpfr_div_2exp(value.backend().data(), value.backend().data(), boost::multiprecision::detail::digits10_2_2(number_type::thread_default_precision()) - 1, GMP_RNDN);
3549 return value;
3550 }
3551 static number_type round_error()
3552 {
3553 return 0.5;
3554 }
3555 static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
3556 static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
3557 static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
3558 static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
3559 static constexpr bool has_infinity = true;
3560 static constexpr bool has_quiet_NaN = true;
3561 static constexpr bool has_signaling_NaN = false;
3562 #ifdef _MSC_VER
3563 #pragma warning(push)
3564 #pragma warning(disable : 4996)
3565 #endif
3566 static constexpr float_denorm_style has_denorm = denorm_absent;
3567 #ifdef _MSC_VER
3568 #pragma warning(pop)
3569 #endif
3570 static constexpr bool has_denorm_loss = false;
3571 static number_type infinity()
3572 {
3573 number_type value;
3574 mpfr_set_inf(value.backend().data(), 1);
3575 return value;
3576 }
3577 static number_type quiet_NaN()
3578 {
3579 number_type value;
3580 mpfr_set_nan(value.backend().data());
3581 return value;
3582 }
3583 static number_type signaling_NaN() { return number_type(0); }
3584 static number_type denorm_min() { return (min)(); }
3585 static constexpr bool is_iec559 = false;
3586 static constexpr bool is_bounded = true;
3587 static constexpr bool is_modulo = false;
3588 static constexpr bool traps = false;
3589 static constexpr bool tinyness_before = false;
3590 static constexpr float_round_style round_style = round_toward_zero;
3591 };
3592
3593 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3594 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
3595 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3596 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
3597 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3598 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
3599 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3600 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
3601 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3602 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
3603 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3604 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
3605 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3606 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
3607 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3608 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
3609 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3610 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
3611 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3612 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
3613 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3614 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
3615 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3616 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
3617 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3618 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
3619 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3620 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
3621 #ifdef _MSC_VER
3622 #pragma warning(push)
3623 #pragma warning(disable : 4996)
3624 #endif
3625 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3626 constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
3627 #ifdef _MSC_VER
3628 #pragma warning(pop)
3629 #endif
3630 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3631 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
3632 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3633 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
3634 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3635 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
3636 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3637 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
3638 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3639 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
3640 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3641 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
3642 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3643 constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;
3644
3645 }
3646 #endif