File indexing completed on 2025-01-18 09:42:36
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 if (round_up)
0857 {
0858 ++e;
0859 ps[offset] = '1';
0860 ps[offset + 1] = 0;
0861 }
0862 else
0863 {
0864 ps[offset] = '0';
0865 ps[offset + 1] = 0;
0866 }
0867 }
0868 else
0869 {
0870 ps[offset] = '0';
0871 ps[offset + 1] = 0;
0872 }
0873 }
0874 else if (digits > 0)
0875 {
0876 ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
0877 --e;
0878 }
0879 else
0880 {
0881 ps = mpfr_get_str(nullptr, &e, 10, 1, m_data, GMP_RNDN);
0882 --e;
0883 unsigned offset = *ps == '-' ? 1 : 0;
0884 ps[offset] = '0';
0885 ps[offset + 1] = 0;
0886 }
0887 }
0888 result = ps ? ps : "0";
0889 if (ps)
0890 mpfr_free_str(ps);
0891 }
0892 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
0893 return result;
0894 }
0895 void negate() noexcept
0896 {
0897 mpfr_neg(m_data, m_data, GMP_RNDN);
0898 }
0899 template <mpfr_allocation_type AllocationType>
0900 int compare(const mpfr_float_backend<digits10, AllocationType>& o) const
0901 {
0902 return mpfr_cmp(m_data, o.m_data);
0903 }
0904 int compare(long i) const
0905 {
0906 return mpfr_cmp_si(m_data, i);
0907 }
0908 int compare(unsigned long i) const
0909 {
0910 return mpfr_cmp_ui(m_data, i);
0911 }
0912 int compare(double i) const
0913 {
0914 return mpfr_cmp_d(m_data, i);
0915 }
0916 int compare(long double i) const
0917 {
0918 return mpfr_cmp_ld(m_data, i);
0919 }
0920 template <class V>
0921 int compare(V v) const
0922 {
0923 mpfr_float_backend<digits10, allocate_stack> d;
0924 d = v;
0925 return compare(d);
0926 }
0927 mpfr_t& data() noexcept
0928 {
0929 return m_data;
0930 }
0931 const mpfr_t& data() const noexcept
0932 {
0933 return m_data;
0934 }
0935
0936 protected:
0937 mpfr_t m_data;
0938 mp_limb_t m_buffer[limb_count];
0939 };
0940
0941 #ifdef BOOST_MSVC
0942 #pragma warning(pop)
0943 #endif
0944
0945 }
0946
0947 template <unsigned digits10, mpfr_allocation_type AllocationType>
0948 struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
0949 {
0950 mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
0951 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
0952
0953 mpfr_float_backend(mpfr_float_backend&& o) noexcept : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o))
0954 {}
0955 template <unsigned D, mpfr_allocation_type AT>
0956 mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
0957 : detail::mpfr_float_imp<digits10, AllocationType>()
0958 {
0959 mpfr_set(this->m_data, val.data(), GMP_RNDN);
0960 }
0961 template <unsigned D, mpfr_allocation_type AT>
0962 explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
0963 : detail::mpfr_float_imp<digits10, AllocationType>()
0964 {
0965 mpfr_set(this->m_data, val.data(), GMP_RNDN);
0966 }
0967 template <unsigned D>
0968 mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
0969 : detail::mpfr_float_imp<digits10, AllocationType>()
0970 {
0971 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
0972 }
0973 template <unsigned D>
0974 mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
0975 : detail::mpfr_float_imp<digits10, AllocationType>()
0976 {
0977 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
0978 }
0979 mpfr_float_backend(const gmp_int& val)
0980 : detail::mpfr_float_imp<digits10, AllocationType>()
0981 {
0982 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
0983 }
0984 mpfr_float_backend(const gmp_rational& val)
0985 : detail::mpfr_float_imp<digits10, AllocationType>()
0986 {
0987 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
0988 }
0989 mpfr_float_backend(const mpfr_t val)
0990 : detail::mpfr_float_imp<digits10, AllocationType>()
0991 {
0992 mpfr_set(this->m_data, val, GMP_RNDN);
0993 }
0994 mpfr_float_backend(const mpf_t val)
0995 : detail::mpfr_float_imp<digits10, AllocationType>()
0996 {
0997 mpfr_set_f(this->m_data, val, GMP_RNDN);
0998 }
0999 mpfr_float_backend(const mpz_t val)
1000 : detail::mpfr_float_imp<digits10, AllocationType>()
1001 {
1002 mpfr_set_z(this->m_data, val, GMP_RNDN);
1003 }
1004 mpfr_float_backend(const mpq_t val)
1005 : detail::mpfr_float_imp<digits10, AllocationType>()
1006 {
1007 mpfr_set_q(this->m_data, val, GMP_RNDN);
1008 }
1009
1010 template <class V>
1011 mpfr_float_backend(const V& o, unsigned)
1012 {
1013 *this = o;
1014 }
1015 mpfr_float_backend& operator=(const mpfr_float_backend& o)
1016 {
1017 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
1018 return *this;
1019 }
1020
1021 mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept
1022 {
1023 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
1024 return *this;
1025 }
1026 template <class V>
1027 typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<digits10, AllocationType>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
1028 {
1029 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
1030 return *this;
1031 }
1032 mpfr_float_backend& operator=(const mpfr_t val)
1033 {
1034 if (this->m_data[0]._mpfr_d == nullptr)
1035 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1036 mpfr_set(this->m_data, val, GMP_RNDN);
1037 return *this;
1038 }
1039 mpfr_float_backend& operator=(const mpf_t val)
1040 {
1041 if (this->m_data[0]._mpfr_d == nullptr)
1042 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1043 mpfr_set_f(this->m_data, val, GMP_RNDN);
1044 return *this;
1045 }
1046 mpfr_float_backend& operator=(const mpz_t val)
1047 {
1048 if (this->m_data[0]._mpfr_d == nullptr)
1049 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1050 mpfr_set_z(this->m_data, val, GMP_RNDN);
1051 return *this;
1052 }
1053 mpfr_float_backend& operator=(const mpq_t val)
1054 {
1055 if (this->m_data[0]._mpfr_d == nullptr)
1056 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1057 mpfr_set_q(this->m_data, val, GMP_RNDN);
1058 return *this;
1059 }
1060
1061 template <unsigned D, mpfr_allocation_type AT>
1062 mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
1063 {
1064 if (this->m_data[0]._mpfr_d == nullptr)
1065 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1066 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1067 return *this;
1068 }
1069 template <unsigned D>
1070 mpfr_float_backend& operator=(const gmp_float<D>& val)
1071 {
1072 if (this->m_data[0]._mpfr_d == nullptr)
1073 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1074 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1075 return *this;
1076 }
1077 mpfr_float_backend& operator=(const gmp_int& val)
1078 {
1079 if (this->m_data[0]._mpfr_d == nullptr)
1080 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1081 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1082 return *this;
1083 }
1084 mpfr_float_backend& operator=(const gmp_rational& val)
1085 {
1086 if (this->m_data[0]._mpfr_d == nullptr)
1087 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1088 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1089 return *this;
1090 }
1091 };
1092
1093 template <>
1094 struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
1095 {
1096 mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
1097 mpfr_float_backend(const mpfr_t val)
1098 : 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())))
1099 {
1100 mpfr_set(this->m_data, val, GMP_RNDN);
1101 }
1102 mpfr_float_backend(const mpf_t val)
1103 : 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())))
1104 {
1105 mpfr_set_f(this->m_data, val, GMP_RNDN);
1106 }
1107 mpfr_float_backend(const mpz_t val)
1108 : detail::mpfr_float_imp<0, allocate_dynamic>()
1109 {
1110 mpfr_set_z(this->m_data, val, GMP_RNDN);
1111 }
1112 mpfr_float_backend(const mpq_t val)
1113 : detail::mpfr_float_imp<0, allocate_dynamic>()
1114 {
1115 mpfr_set_q(this->m_data, val, GMP_RNDN);
1116 }
1117 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
1118
1119 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))
1120 {}
1121 template <class V>
1122 mpfr_float_backend(const V& o, unsigned digits10)
1123 : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
1124 {
1125 *this = o;
1126 }
1127 #ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
1128 mpfr_float_backend(const std::string_view& o, unsigned digits10)
1129 : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
1130 {
1131 std::string s(o);
1132 *this = s.c_str();
1133 }
1134 #endif
1135 template <unsigned D>
1136 mpfr_float_backend(const gmp_float<D>& val, unsigned digits10)
1137 : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
1138 {
1139 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1140 }
1141 template <unsigned D>
1142 mpfr_float_backend(const mpfr_float_backend<D>& val, unsigned digits10)
1143 : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
1144 {
1145 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1146 }
1147 template <unsigned D>
1148 mpfr_float_backend(const mpfr_float_backend<D>& val)
1149 : 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())))
1150 {
1151 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1152 }
1153 template <unsigned D>
1154 mpfr_float_backend(const gmp_float<D>& val)
1155 : 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())))
1156 {
1157 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1158 }
1159 mpfr_float_backend(const gmp_int& val)
1160 : 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())))
1161 {
1162 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1163 }
1164 mpfr_float_backend(const gmp_rational& val)
1165 : 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())))
1166 {
1167 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1168 }
1169
1170 mpfr_float_backend& operator=(const mpfr_float_backend& o) = default;
1171
1172 mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept = default;
1173
1174 template <class V>
1175 typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<0, allocate_dynamic>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
1176 {
1177 constexpr unsigned d10 = std::is_floating_point<V>::value ?
1178 std::numeric_limits<V>::digits10 :
1179 std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 :
1180 1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits);
1181
1182 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1183 {
1184 BOOST_IF_CONSTEXPR(std::is_floating_point<V>::value)
1185 {
1186 if (std::numeric_limits<V>::digits > mpfr_get_prec(this->data()))
1187 mpfr_set_prec(this->data(), std::numeric_limits<V>::digits);
1188 }
1189 else
1190 {
1191 if(precision() < d10)
1192 this->precision(d10);
1193 }
1194 }
1195
1196 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
1197 return *this;
1198 }
1199 mpfr_float_backend& operator=(const mpfr_t val)
1200 {
1201 if (this->m_data[0]._mpfr_d == nullptr)
1202 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())));
1203 else if(preserve_all_precision())
1204 mpfr_set_prec(this->m_data, mpfr_get_prec(val));
1205 mpfr_set(this->m_data, val, GMP_RNDN);
1206 return *this;
1207 }
1208 mpfr_float_backend& operator=(const mpf_t val)
1209 {
1210 if (this->m_data[0]._mpfr_d == nullptr)
1211 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())));
1212 else if(preserve_all_precision())
1213 mpfr_set_prec(this->m_data, static_cast<mpfr_prec_t>(mpf_get_prec(val)));
1214 mpfr_set_f(this->m_data, val, GMP_RNDN);
1215 return *this;
1216 }
1217 mpfr_float_backend& operator=(const mpz_t val)
1218 {
1219 if (this->m_data[0]._mpfr_d == nullptr)
1220 mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(get_default_precision())));
1221 mpfr_set_z(this->m_data, val, GMP_RNDN);
1222 return *this;
1223 }
1224 mpfr_float_backend& operator=(const mpq_t val)
1225 {
1226 if (this->m_data[0]._mpfr_d == nullptr)
1227 mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(get_default_precision())));
1228 mpfr_set_q(this->m_data, val, GMP_RNDN);
1229 return *this;
1230 }
1231 template <unsigned D>
1232 mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
1233 {
1234 if (this->m_data[0]._mpfr_d == nullptr)
1235 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()));
1236 else if (preserve_related_precision())
1237 mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
1238 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1239 return *this;
1240 }
1241 template <unsigned D>
1242 mpfr_float_backend& operator=(const gmp_float<D>& val)
1243 {
1244 if (this->m_data[0]._mpfr_d == nullptr)
1245 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()));
1246 else if (preserve_all_precision())
1247 mpfr_set_prec(this->m_data, static_cast<mpfr_prec_t>(mpf_get_prec(val.data())));
1248 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1249 return *this;
1250 }
1251 mpfr_float_backend& operator=(const gmp_int& val)
1252 {
1253 if (this->m_data[0]._mpfr_d == nullptr)
1254 {
1255 unsigned requested_precision = this->thread_default_precision();
1256 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1257 {
1258 unsigned d2 = static_cast<unsigned>(used_gmp_int_bits(val));
1259 unsigned d10 = static_cast<unsigned>(1ULL + multiprecision::detail::digits2_2_10(d2));
1260 if (d10 > requested_precision)
1261 requested_precision = d10;
1262 }
1263 mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(requested_precision)));
1264 }
1265 else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1266 {
1267 unsigned requested_precision = this->thread_default_precision();
1268 unsigned d2 = static_cast<unsigned>(used_gmp_int_bits(val));
1269 unsigned d10 = static_cast<unsigned>(1ULL + multiprecision::detail::digits2_2_10(d2));
1270 if (d10 > requested_precision)
1271 this->precision(d10);
1272 }
1273 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1274 return *this;
1275 }
1276 mpfr_float_backend& operator=(const gmp_rational& val)
1277 {
1278 if (this->m_data[0]._mpfr_d == nullptr)
1279 {
1280 unsigned requested_precision = this->get_default_precision();
1281 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1282 {
1283 unsigned d10 = static_cast<unsigned>(1u + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)));
1284 if (d10 > requested_precision)
1285 requested_precision = d10;
1286 }
1287 mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(requested_precision)));
1288 }
1289 else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1290 {
1291 unsigned requested_precision = this->get_default_precision();
1292 unsigned d10 = static_cast<unsigned>(1u + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)));
1293 if (d10 > requested_precision)
1294 this->precision(d10);
1295 }
1296 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1297 return *this;
1298 }
1299 static unsigned default_precision() noexcept
1300 {
1301 return get_global_default_precision();
1302 }
1303 static void default_precision(unsigned v) noexcept
1304 {
1305 get_global_default_precision() = v;
1306 }
1307 static unsigned thread_default_precision() noexcept
1308 {
1309 return get_default_precision();
1310 }
1311 static void thread_default_precision(unsigned v) noexcept
1312 {
1313 get_default_precision() = v;
1314 }
1315 unsigned precision() const noexcept
1316 {
1317 return static_cast<unsigned>(multiprecision::detail::digits2_2_10(static_cast<unsigned long>(mpfr_get_prec(this->m_data))));
1318 }
1319 void precision(unsigned digits10) noexcept
1320 {
1321 mpfr_prec_round(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2((digits10))), GMP_RNDN);
1322 }
1323
1324
1325
1326 static variable_precision_options default_variable_precision_options()noexcept
1327 {
1328 return get_global_default_options();
1329 }
1330 static variable_precision_options thread_default_variable_precision_options()noexcept
1331 {
1332 return get_default_options();
1333 }
1334 static void default_variable_precision_options(variable_precision_options opts)
1335 {
1336 get_global_default_options() = opts;
1337 }
1338 static void thread_default_variable_precision_options(variable_precision_options opts)
1339 {
1340 get_default_options() = opts;
1341 }
1342 static bool preserve_source_precision()
1343 {
1344 return get_default_options() >= variable_precision_options::preserve_source_precision;
1345 }
1346 static bool preserve_related_precision()
1347 {
1348 return get_default_options() >= variable_precision_options::preserve_related_precision;
1349 }
1350 static bool preserve_all_precision()
1351 {
1352 return get_default_options() >= variable_precision_options::preserve_all_precision;
1353 }
1354 };
1355
1356 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1357 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)
1358 {
1359 return a.compare(b) == 0;
1360 }
1361 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1362 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)
1363 {
1364 return a.compare(b) < 0;
1365 }
1366 template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1367 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)
1368 {
1369 return a.compare(b) > 0;
1370 }
1371
1372 template <unsigned digits10, mpfr_allocation_type AllocationType>
1373 inline bool eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b)noexcept
1374 {
1375 return mpfr_equal_p(a.data(), b.data());
1376 }
1377 template <unsigned digits10, mpfr_allocation_type AllocationType>
1378 inline bool eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
1379 {
1380 return mpfr_less_p(a.data(), b.data());
1381 }
1382 template <unsigned digits10, mpfr_allocation_type AllocationType>
1383 inline bool eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
1384 {
1385 return mpfr_greater_p(a.data(), b.data());
1386 }
1387
1388 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1389 inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1390 {
1391 mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
1392 }
1393 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1394 inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1395 {
1396 mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
1397 }
1398 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1399 inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1400 {
1401 if ((void*)&o == (void*)&result)
1402 mpfr_sqr(result.data(), o.data(), GMP_RNDN);
1403 else
1404 mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
1405 }
1406 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1407 inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1408 {
1409 mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
1410 }
1411 template <unsigned digits10, mpfr_allocation_type AllocationType>
1412 inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1413 {
1414 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1415 }
1416 template <unsigned digits10, mpfr_allocation_type AllocationType>
1417 inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1418 {
1419 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
1420 }
1421 template <unsigned digits10, mpfr_allocation_type AllocationType>
1422 inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1423 {
1424 mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
1425 }
1426 template <unsigned digits10, mpfr_allocation_type AllocationType>
1427 inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1428 {
1429 mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
1430 }
1431 template <unsigned digits10, mpfr_allocation_type AllocationType>
1432 inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
1433 {
1434 if (i > 0)
1435 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1436 else
1437 mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1438 }
1439 template <unsigned digits10, mpfr_allocation_type AllocationType>
1440 inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
1441 {
1442 if (i > 0)
1443 mpfr_sub_ui(result.data(), result.data(), static_cast<typename std::make_unsigned<long>::type>(i), GMP_RNDN);
1444 else
1445 mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1446 }
1447 template <unsigned digits10, mpfr_allocation_type AllocationType>
1448 inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
1449 {
1450 mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1451 if (i < 0)
1452 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1453 }
1454 template <unsigned digits10, mpfr_allocation_type AllocationType>
1455 inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
1456 {
1457 mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1458 if (i < 0)
1459 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1460 }
1461
1462
1463
1464 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1465 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
1466 {
1467 mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
1468 }
1469 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1470 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1471 {
1472 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1473 }
1474 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1475 inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1476 {
1477 if (y < 0)
1478 mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1479 else
1480 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1481 }
1482 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1483 inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1484 {
1485 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1486 }
1487 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1488 inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1489 {
1490 if (x < 0)
1491 {
1492 mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1493 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1494 }
1495 else
1496 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1497 }
1498 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1499 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
1500 {
1501 mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
1502 }
1503 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1504 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1505 {
1506 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1507 }
1508 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1509 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1510 {
1511 if (y < 0)
1512 mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1513 else
1514 mpfr_sub_ui(a.data(), x.data(), static_cast<typename std::make_unsigned<long>::type>(y), GMP_RNDN);
1515 }
1516 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1517 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1518 {
1519 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1520 }
1521 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1522 inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1523 {
1524 if (x < 0)
1525 {
1526 mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1527 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1528 }
1529 else
1530 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1531 }
1532
1533 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1534 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
1535 {
1536 if ((void*)&x == (void*)&y)
1537 mpfr_sqr(a.data(), x.data(), GMP_RNDN);
1538 else
1539 mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
1540 }
1541 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1542 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1543 {
1544 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1545 }
1546 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1547 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1548 {
1549 if (y < 0)
1550 {
1551 mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1552 a.negate();
1553 }
1554 else
1555 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1556 }
1557 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1558 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1559 {
1560 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1561 }
1562 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1563 inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1564 {
1565 if (x < 0)
1566 {
1567 mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1568 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1569 }
1570 else
1571 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1572 }
1573
1574 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1575 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
1576 {
1577 mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
1578 }
1579 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1580 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1581 {
1582 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1583 }
1584 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1585 inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1586 {
1587 if (y < 0)
1588 {
1589 mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1590 a.negate();
1591 }
1592 else
1593 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1594 }
1595 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1596 inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1597 {
1598 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1599 }
1600 template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1601 inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1602 {
1603 if (x < 0)
1604 {
1605 mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1606 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1607 }
1608 else
1609 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1610 }
1611
1612 template <unsigned digits10, mpfr_allocation_type AllocationType>
1613 inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1614 {
1615 return 0 != mpfr_zero_p(val.data());
1616 }
1617 template <unsigned digits10, mpfr_allocation_type AllocationType>
1618 inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1619 {
1620 return mpfr_sgn(val.data());
1621 }
1622
1623 template <unsigned digits10, mpfr_allocation_type AllocationType>
1624 inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1625 {
1626 if (mpfr_nan_p(val.data()))
1627 {
1628 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1629 }
1630 *result = mpfr_get_ui(val.data(), GMP_RNDZ);
1631 }
1632 template <unsigned digits10, mpfr_allocation_type AllocationType>
1633 inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1634 {
1635 if (mpfr_nan_p(val.data()))
1636 {
1637 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1638 }
1639 *result = mpfr_get_si(val.data(), GMP_RNDZ);
1640 }
1641 #ifdef _MPFR_H_HAVE_INTMAX_T
1642 template <unsigned digits10, mpfr_allocation_type AllocationType>
1643 inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1644 {
1645 if (mpfr_nan_p(val.data()))
1646 {
1647 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1648 }
1649 *result = mpfr_get_uj(val.data(), GMP_RNDZ);
1650 }
1651 template <unsigned digits10, mpfr_allocation_type AllocationType>
1652 inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1653 {
1654 if (mpfr_nan_p(val.data()))
1655 {
1656 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1657 }
1658 *result = mpfr_get_sj(val.data(), GMP_RNDZ);
1659 }
1660 #endif
1661 template <unsigned digits10, mpfr_allocation_type AllocationType>
1662 inline void eval_convert_to(float* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1663 {
1664 *result = mpfr_get_flt(val.data(), GMP_RNDN);
1665 }
1666 template <unsigned digits10, mpfr_allocation_type AllocationType>
1667 inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1668 {
1669 *result = mpfr_get_d(val.data(), GMP_RNDN);
1670 }
1671 template <unsigned digits10, mpfr_allocation_type AllocationType>
1672 inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1673 {
1674 *result = mpfr_get_ld(val.data(), GMP_RNDN);
1675 }
1676
1677 #ifdef BOOST_HAS_INT128
1678 template <unsigned digits10, mpfr_allocation_type AllocationType>
1679 inline void eval_convert_to(int128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1680 {
1681 gmp_int i;
1682 mpfr_get_z(i.data(), val.data(), GMP_RNDN);
1683 eval_convert_to(result, i);
1684 }
1685 template <unsigned digits10, mpfr_allocation_type AllocationType>
1686 inline void eval_convert_to(uint128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1687 {
1688 gmp_int i;
1689 mpfr_get_z(i.data(), val.data(), GMP_RNDN);
1690 eval_convert_to(result, i);
1691 }
1692 #endif
1693 #if defined(BOOST_HAS_FLOAT128)
1694 template <unsigned digits10, mpfr_allocation_type AllocationType>
1695 inline void eval_convert_to(float128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1696 {
1697 *result = float128_procs::strtoflt128(val.str(0, std::ios_base::scientific).c_str(), nullptr);
1698 }
1699 #endif
1700
1701
1702
1703
1704 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1705 inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1706 {
1707 mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
1708 }
1709
1710 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1711 inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1712 {
1713 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1714 }
1715
1716 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1717 inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1718 {
1719 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1720 }
1721 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1722 inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1723 {
1724 mpfr_ceil(result.data(), val.data());
1725 }
1726 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1727 inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1728 {
1729 mpfr_floor(result.data(), val.data());
1730 }
1731 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1732 inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1733 {
1734 mpfr_trunc(result.data(), val.data());
1735 }
1736 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1737 inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
1738 {
1739 using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
1740
1741 if (e > 0)
1742 mpfr_mul_2exp(result.data(), val.data(), static_cast<local_uint_type>(e), GMP_RNDN);
1743 else if (e < 0)
1744 mpfr_div_2exp(result.data(), val.data(), static_cast<local_uint_type>(-e), GMP_RNDN);
1745 else
1746 result = val;
1747 }
1748 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1749 inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
1750 {
1751 if (mpfr_zero_p(val.data()))
1752 {
1753 *e = 0;
1754 result = val;
1755 return;
1756 }
1757 mp_exp_t v = mpfr_get_exp(val.data());
1758 *e = static_cast<int>(v);
1759 if (v)
1760 eval_ldexp(result, val, -v);
1761 else
1762 result = val;
1763 }
1764 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1765 inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
1766 {
1767 if (mpfr_zero_p(val.data()))
1768 {
1769 *e = 0;
1770 result = val;
1771 return;
1772 }
1773 mp_exp_t v = mpfr_get_exp(val.data());
1774 *e = v;
1775 if(v)
1776 eval_ldexp(result, val, -v);
1777 else
1778 result = val;
1779 }
1780
1781 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1782 inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) noexcept
1783 {
1784 return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
1785 }
1786
1787 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1788 inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
1789 {
1790 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))
1791 {
1792 mpfr_set(result.data(), b.data(), GMP_RNDN);
1793 }
1794 else
1795 mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1796 }
1797
1798 #ifdef BOOST_MSVC
1799
1800
1801
1802
1803
1804 #define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10)&&
1805 #else
1806 #define BOOST_MP_ENABLE_IF_WORKAROUND
1807 #endif
1808
1809 template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1810 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
1811 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
1812 {
1813 mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
1814 }
1815
1816 template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1817 inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value && (BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long)))>::type
1818 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
1819 {
1820 mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
1821 }
1822
1823 #undef BOOST_MP_ENABLE_IF_WORKAROUND
1824
1825 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1826 inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1827 {
1828 mpfr_exp(result.data(), arg.data(), GMP_RNDN);
1829 }
1830
1831 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1832 inline void eval_exp2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1833 {
1834 mpfr_exp2(result.data(), arg.data(), GMP_RNDN);
1835 }
1836
1837 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1838 inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1839 {
1840 mpfr_log(result.data(), arg.data(), GMP_RNDN);
1841 }
1842
1843 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1844 inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1845 {
1846 mpfr_log10(result.data(), arg.data(), GMP_RNDN);
1847 }
1848
1849 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1850 inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1851 {
1852 mpfr_sin(result.data(), arg.data(), GMP_RNDN);
1853 }
1854
1855 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1856 inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1857 {
1858 mpfr_cos(result.data(), arg.data(), GMP_RNDN);
1859 }
1860
1861 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1862 inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1863 {
1864 mpfr_tan(result.data(), arg.data(), GMP_RNDN);
1865 }
1866
1867 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1868 inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1869 {
1870 mpfr_asin(result.data(), arg.data(), GMP_RNDN);
1871 }
1872
1873 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1874 inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1875 {
1876 mpfr_acos(result.data(), arg.data(), GMP_RNDN);
1877 }
1878
1879 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1880 inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1881 {
1882 mpfr_atan(result.data(), arg.data(), GMP_RNDN);
1883 }
1884
1885 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1886 inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
1887 {
1888 mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
1889 }
1890
1891 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1892 inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1893 {
1894 mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
1895 }
1896
1897 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1898 inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1899 {
1900 mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
1901 }
1902
1903 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1904 inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1905 {
1906 mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
1907 }
1908
1909 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1910 inline void eval_log2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1911 {
1912 mpfr_log2(result.data(), arg.data(), GMP_RNDN);
1913 }
1914
1915 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1916 inline void eval_modf(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg, mpfr_float_backend<Digits10, AllocateType>* pipart)
1917 {
1918 if (pipart == nullptr)
1919 {
1920 mpfr_float_backend<Digits10, AllocateType> ipart;
1921 mpfr_modf(ipart.data(), result.data(), arg.data(), GMP_RNDN);
1922 }
1923 else
1924 {
1925 mpfr_modf(pipart->data(), result.data(), arg.data(), GMP_RNDN);
1926 }
1927 }
1928 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1929 inline void eval_remainder(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1930 {
1931 mpfr_remainder(result.data(), a.data(), b.data(), GMP_RNDN);
1932 }
1933 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1934 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)
1935 {
1936 long l;
1937 mpfr_remquo(result.data(), &l, a.data(), b.data(), GMP_RNDN);
1938 if (pi)
1939 *pi = static_cast<int>(l);
1940 }
1941
1942 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1943 inline void eval_fmod(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1944 {
1945 mpfr_fmod(result.data(), a.data(), b.data(), GMP_RNDN);
1946 }
1947
1948 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1949 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)
1950 {
1951 mpfr_fma(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1952 }
1953
1954 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1955 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)
1956 {
1957 mpfr_fma(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1958 }
1959
1960 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1961 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)
1962 {
1963 mpfr_fms(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1964 result.negate();
1965 }
1966
1967 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1968 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)
1969 {
1970 mpfr_fms(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1971 }
1972
1973 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1974 inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const mpfr_float_backend<Digits10, AllocateType>& arg)
1975 {
1976 return (arg.data()[0]._mpfr_sign < 0) ? 1 : 0;
1977 }
1978
1979 template <unsigned Digits10, mpfr_allocation_type AllocateType>
1980 inline std::size_t hash_value(const mpfr_float_backend<Digits10, AllocateType>& val)
1981 {
1982 std::size_t result = 0;
1983 std::size_t len = val.data()[0]._mpfr_prec / mp_bits_per_limb;
1984 if (val.data()[0]._mpfr_prec % mp_bits_per_limb)
1985 ++len;
1986 for (std::size_t i = 0; i < len; ++i)
1987 boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_d[i]);
1988 boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_exp, val.data()[0]._mpfr_sign);
1989 return result;
1990 }
1991
1992 }
1993
1994 namespace detail {
1995 template <>
1996 struct is_variable_precision<backends::mpfr_float_backend<0> > : public std::integral_constant<bool, true>
1997 {};
1998 }
1999
2000 template <>
2001 struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public std::integral_constant<int, number_kind_floating_point>
2002 {};
2003
2004 template <unsigned D, boost::multiprecision::mpfr_allocation_type A1, boost::multiprecision::mpfr_allocation_type A2>
2005 struct is_equivalent_number_type<backends::mpfr_float_backend<D, A1>, backends::mpfr_float_backend<D, A2> > : public std::integral_constant<bool, true> {};
2006
2007 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2008 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)
2009 {
2010 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(-a) : a;
2011 }
2012
2013 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2014 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)
2015 {
2016 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;
2017 }
2018
2019 }
2020
2021 namespace math {
2022
2023 using boost::multiprecision::copysign;
2024 using boost::multiprecision::signbit;
2025
2026 namespace tools {
2027
2028 #ifndef BOOST_MP_MATH_AVAILABLE
2029
2030 template <typename T>
2031 inline int digits();
2032
2033 template <typename T>
2034 inline T max_value();
2035
2036 template <typename T>
2037 inline T min_value();
2038
2039 #endif
2040
2041 inline void set_output_precision(const boost::multiprecision::mpfr_float& val, std::ostream& os)
2042 {
2043 os << std::setprecision(static_cast<int>(val.precision()));
2044 }
2045
2046 template <>
2047 inline int digits<boost::multiprecision::mpfr_float>()
2048 #ifdef BOOST_MATH_NOEXCEPT
2049 noexcept
2050 #endif
2051 {
2052 return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision()));
2053 }
2054 template <>
2055 inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
2056 #ifdef BOOST_MATH_NOEXCEPT
2057 noexcept
2058 #endif
2059 {
2060 return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision()));
2061 }
2062
2063 template <>
2064 inline boost::multiprecision::mpfr_float
2065 max_value<boost::multiprecision::mpfr_float>()
2066 {
2067 boost::multiprecision::mpfr_float result(0.5);
2068 mpfr_mul_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(mpfr_get_emax()), GMP_RNDN);
2069 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
2070 return result;
2071 }
2072
2073 template <>
2074 inline boost::multiprecision::mpfr_float
2075 min_value<boost::multiprecision::mpfr_float>()
2076 {
2077 boost::multiprecision::mpfr_float result(0.5);
2078 mpfr_div_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(-mpfr_get_emin()), GMP_RNDN);
2079 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
2080 return result;
2081 }
2082
2083 template <>
2084 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
2085 max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
2086 {
2087 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
2088 mpfr_mul_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(mpfr_get_emax()), GMP_RNDN);
2089 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
2090 return result;
2091 }
2092
2093 template <>
2094 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
2095 min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
2096 {
2097 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
2098 mpfr_div_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(-mpfr_get_emin()), GMP_RNDN);
2099 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
2100 return result;
2101 }
2102
2103
2104
2105 template <>
2106 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2107 #ifdef BOOST_MATH_NOEXCEPT
2108 noexcept
2109 #endif
2110 {
2111 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()));
2112 }
2113 template <>
2114 inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2115 #ifdef BOOST_MATH_NOEXCEPT
2116 noexcept
2117 #endif
2118 {
2119 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()));
2120 }
2121
2122 template <>
2123 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2124 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2125 {
2126 return max_value<boost::multiprecision::mpfr_float>().backend();
2127 }
2128
2129 template <>
2130 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2131 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2132 {
2133 return min_value<boost::multiprecision::mpfr_float>().backend();
2134 }
2135
2136 template <>
2137 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2138 max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2139 {
2140 return max_value<boost::multiprecision::mpfr_float>().backend();
2141 }
2142
2143 template <>
2144 inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2145 min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2146 {
2147 return min_value<boost::multiprecision::mpfr_float>().backend();
2148 }
2149
2150
2151
2152
2153 template <>
2154 inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2155 #ifdef BOOST_MATH_NOEXCEPT
2156 noexcept
2157 #endif
2158 {
2159 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()));
2160 }
2161 template <>
2162 inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2163 #ifdef BOOST_MATH_NOEXCEPT
2164 noexcept
2165 #endif
2166 {
2167 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()));
2168 }
2169
2170 template <>
2171 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2172 max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2173 {
2174 return max_value<boost::multiprecision::mpfr_float>().backend();
2175 }
2176
2177 template <>
2178 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2179 min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2180 {
2181 return min_value<boost::multiprecision::mpfr_float>().backend();
2182 }
2183
2184 template <>
2185 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2186 max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2187 {
2188 return max_value<boost::multiprecision::mpfr_float>().backend();
2189 }
2190
2191 template <>
2192 inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2193 min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2194 {
2195 return min_value<boost::multiprecision::mpfr_float>().backend();
2196 }
2197
2198 }
2199
2200 namespace constants { namespace detail {
2201
2202 template <class T>
2203 struct constant_pi;
2204 template <class T>
2205 struct constant_ln_two;
2206 template <class T>
2207 struct constant_euler;
2208 template <class T>
2209 struct constant_catalan;
2210
2211 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2212 struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2213 {
2214 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
2215 template <int N>
2216 static inline const result_type& get(const std::integral_constant<int, N>&)
2217 {
2218
2219 static result_type result{get(std::integral_constant<int, 0>())};
2220 return result;
2221 }
2222 static inline const result_type get(const std::integral_constant<int, 0>&)
2223 {
2224 result_type result;
2225 mpfr_const_pi(result.backend().data(), GMP_RNDN);
2226 return result;
2227 }
2228 };
2229 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2230 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2231 {
2232 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
2233 template <int N>
2234 static inline const result_type& get(const std::integral_constant<int, N>&)
2235 {
2236
2237 static result_type result{get(std::integral_constant<int, 0>())};
2238 return result;
2239 }
2240 static inline const result_type get(const std::integral_constant<int, 0>&)
2241 {
2242 result_type result;
2243 mpfr_const_log2(result.backend().data(), GMP_RNDN);
2244 return result;
2245 }
2246 };
2247 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2248 struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2249 {
2250 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
2251 template <int N>
2252 static inline const result_type& get(const std::integral_constant<int, N>&)
2253 {
2254
2255 static result_type result{get(std::integral_constant<int, 0>())};
2256 return result;
2257 }
2258 static inline const result_type get(const std::integral_constant<int, 0>&)
2259 {
2260 result_type result;
2261 mpfr_const_euler(result.backend().data(), GMP_RNDN);
2262 return result;
2263 }
2264 };
2265 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2266 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2267 {
2268 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
2269 template <int N>
2270 static inline const result_type& get(const std::integral_constant<int, N>&)
2271 {
2272
2273 static result_type result{get(std::integral_constant<int, 0>())};
2274 return result;
2275 }
2276 static inline const result_type get(const std::integral_constant<int, 0>&)
2277 {
2278 result_type result;
2279 mpfr_const_catalan(result.backend().data(), GMP_RNDN);
2280 return result;
2281 }
2282 };
2283
2284
2285
2286 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2287 struct constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2288 {
2289 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2290 template <int N>
2291 static inline const result_type& get(const std::integral_constant<int, N>&)
2292 {
2293
2294 static result_type result{get(std::integral_constant<int, 0>())};
2295 return result;
2296 }
2297 static inline const result_type get(const std::integral_constant<int, 0>&)
2298 {
2299 result_type result;
2300 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
2301 result.backend().update_view();
2302 return result;
2303 }
2304 };
2305 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2306 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2307 {
2308 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2309 template <int N>
2310 static inline const result_type& get(const std::integral_constant<int, N>&)
2311 {
2312
2313 static result_type result{get(std::integral_constant<int, 0>())};
2314 return result;
2315 }
2316 static inline const result_type get(const std::integral_constant<int, 0>&)
2317 {
2318 result_type result;
2319 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
2320 result.backend().update_view();
2321 return result;
2322 }
2323 };
2324 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2325 struct constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2326 {
2327 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2328 template <int N>
2329 static inline const result_type& get(const std::integral_constant<int, N>&)
2330 {
2331
2332 static result_type result{get(std::integral_constant<int, 0>())};
2333 return result;
2334 }
2335 static inline const result_type get(const std::integral_constant<int, 0>&)
2336 {
2337 result_type result;
2338 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
2339 result.backend().update_view();
2340 return result;
2341 }
2342 };
2343 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2344 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2345 {
2346 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2347 template <int N>
2348 static inline const result_type& get(const std::integral_constant<int, N>&)
2349 {
2350
2351 static result_type result{get(std::integral_constant<int, 0>())};
2352 return result;
2353 }
2354 static inline const result_type get(const std::integral_constant<int, 0>&)
2355 {
2356 result_type result;
2357 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
2358 result.backend().update_view();
2359 return result;
2360 }
2361 };
2362
2363
2364
2365
2366 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2367 struct constant_pi<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2368 {
2369 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2370 template <int N>
2371 static inline const result_type& get(const std::integral_constant<int, N>&)
2372 {
2373
2374 static result_type result{get(std::integral_constant<int, 0>())};
2375 return result;
2376 }
2377 static inline const result_type get(const std::integral_constant<int, 0>&)
2378 {
2379 result_type result;
2380 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
2381 return result;
2382 }
2383 };
2384 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2385 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2386 {
2387 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2388 template <int N>
2389 static inline const result_type& get(const std::integral_constant<int, N>&)
2390 {
2391
2392 static result_type result{get(std::integral_constant<int, 0>())};
2393 return result;
2394 }
2395 static inline const result_type get(const std::integral_constant<int, 0>&)
2396 {
2397 result_type result;
2398 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
2399 return result;
2400 }
2401 };
2402 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2403 struct constant_euler<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2404 {
2405 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2406 template <int N>
2407 static inline const result_type& get(const std::integral_constant<int, N>&)
2408 {
2409
2410 static result_type result{get(std::integral_constant<int, 0>())};
2411 return result;
2412 }
2413 static inline const result_type get(const std::integral_constant<int, 0>&)
2414 {
2415 result_type result;
2416 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
2417 return result;
2418 }
2419 };
2420 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2421 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2422 {
2423 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2424 template <int N>
2425 static inline const result_type& get(const std::integral_constant<int, N>&)
2426 {
2427
2428 static result_type result{get(std::integral_constant<int, 0>())};
2429 return result;
2430 }
2431 static inline const result_type get(const std::integral_constant<int, 0>&)
2432 {
2433 result_type result;
2434 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
2435 return result;
2436 }
2437 };
2438
2439 }}
2440
2441 }
2442
2443 namespace multiprecision {
2444
2445
2446
2447 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2448 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)
2449 {
2450 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2451
2452 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2453 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2454 return result;
2455 }
2456 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2457 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)
2458 {
2459 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2460
2461 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2462 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2463 return result;
2464 }
2465 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2466 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)
2467 {
2468 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2469
2470 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2471 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2472 return result;
2473 }
2474 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2475 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)
2476 {
2477 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2478
2479 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2480 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2481 return result;
2482 }
2483 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2484 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)
2485 {
2486 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2487
2488 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2489 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
2490 return result;
2491 }
2492 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2493 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)
2494 {
2495 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2496
2497 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2498 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
2499 return result;
2500 }
2501 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2502 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)
2503 {
2504 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2505
2506 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2507 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
2508 return result;
2509 }
2510 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2511 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)
2512 {
2513 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2514
2515 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2516 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2517 return result;
2518 }
2519 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2520 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)
2521 {
2522 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2523
2524 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2525 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2526 return result;
2527 }
2528 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2529 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)
2530 {
2531 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2532
2533 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2534 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
2535 return result;
2536 }
2537
2538
2539
2540
2541 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2542 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)
2543 {
2544 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2545
2546 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2547 mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2548 result.backend().update_view();
2549 return result;
2550 }
2551 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2552 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)
2553 {
2554 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2555
2556 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2557 mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2558 result.backend().update_view();
2559 return result;
2560 }
2561 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2562 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)
2563 {
2564 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2565
2566 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2567 mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2568 result.backend().update_view();
2569 return result;
2570 }
2571 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2572 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)
2573 {
2574 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2575
2576 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2577 mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2578 result.backend().update_view();
2579 return result;
2580 }
2581 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2582 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)
2583 {
2584 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2585
2586 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2587 mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2588 result.backend().update_view();
2589 return result;
2590 }
2591 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2592 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)
2593 {
2594 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2595
2596 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2597 mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2598 result.backend().update_view();
2599 return result;
2600 }
2601 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2602 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)
2603 {
2604 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2605
2606 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2607 mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2608 result.backend().update_view();
2609 return result;
2610 }
2611 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2612 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)
2613 {
2614 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2615
2616 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2617 mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2618 result.backend().update_view();
2619 return result;
2620 }
2621 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2622 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)
2623 {
2624 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2625
2626 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2627 mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2628 result.backend().update_view();
2629 return result;
2630 }
2631 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2632 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)
2633 {
2634 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2635
2636 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2637 mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2638 result.backend().update_view();
2639 return result;
2640 }
2641
2642
2643
2644
2645 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2646 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)
2647 {
2648 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2649
2650 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2651 mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2652 return result;
2653 }
2654 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2655 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)
2656 {
2657 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2658
2659 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2660 mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2661 return result;
2662 }
2663 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2664 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)
2665 {
2666 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2667
2668 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2669 mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2670 return result;
2671 }
2672 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2673 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)
2674 {
2675 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2676
2677 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2678 mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2679 return result;
2680 }
2681 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2682 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)
2683 {
2684 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2685
2686 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2687 mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2688 return result;
2689 }
2690 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2691 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)
2692 {
2693 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2694
2695 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2696 mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2697 return result;
2698 }
2699 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2700 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)
2701 {
2702 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2703
2704 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2705 mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2706 return result;
2707 }
2708 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2709 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)
2710 {
2711 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2712
2713 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2714 mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2715 return result;
2716 }
2717 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2718 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)
2719 {
2720 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2721
2722 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2723 mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2724 return result;
2725 }
2726 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2727 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)
2728 {
2729 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2730
2731 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2732 mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2733 return result;
2734 }
2735
2736 }
2737
2738 namespace math {
2739
2740
2741
2742 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2743 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&)
2744 {
2745 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2746
2747 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2748 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2749 if (mpfr_inf_p(result.backend().data()))
2750 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("asinh<%1%>(%1%)", nullptr, Policy());
2751 if (mpfr_nan_p(result.backend().data()))
2752 return policies::raise_evaluation_error("asinh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2753 return result;
2754 }
2755 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2756 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)
2757 {
2758 return asinh(arg, policies::policy<>());
2759 }
2760
2761 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2762 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&)
2763 {
2764 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2765
2766 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2767 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2768 if (mpfr_inf_p(result.backend().data()))
2769 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("acosh<%1%>(%1%)", nullptr, Policy());
2770 if (mpfr_nan_p(result.backend().data()))
2771 return policies::raise_evaluation_error("acosh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2772 return result;
2773 }
2774 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2775 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)
2776 {
2777 return acosh(arg, policies::policy<>());
2778 }
2779
2780 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2781 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& )
2782 {
2783 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2784
2785 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2786 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2787 if (mpfr_inf_p(result.backend().data()))
2788 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("atanh<%1%>(%1%)", nullptr, Policy());
2789 if (mpfr_nan_p(result.backend().data()))
2790 return policies::raise_evaluation_error("atanh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2791 return result;
2792 }
2793 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2794 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)
2795 {
2796 return atanh(arg, policies::policy<>());
2797 }
2798
2799 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2800 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&)
2801 {
2802 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2803
2804 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2805 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2806 if (mpfr_inf_p(result.backend().data()))
2807 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("cbrt<%1%>(%1%)", nullptr, Policy());
2808 if (mpfr_nan_p(result.backend().data()))
2809 return policies::raise_evaluation_error("cbrt<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2810 return result;
2811 }
2812 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2813 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)
2814 {
2815 return cbrt(arg, policies::policy<>());
2816 }
2817
2818 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2819 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)
2820 {
2821 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2822
2823 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2824 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
2825 if (mpfr_inf_p(result.backend().data()))
2826 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erf<%1%>(%1%)", nullptr, pol);
2827 if (mpfr_nan_p(result.backend().data()))
2828 return policies::raise_evaluation_error("erf<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2829 return result;
2830 }
2831 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2832 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)
2833 {
2834 return erf(arg, policies::policy<>());
2835 }
2836
2837 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2838 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)
2839 {
2840 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2841
2842 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2843 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
2844 if (mpfr_inf_p(result.backend().data()))
2845 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erfc<%1%>(%1%)", nullptr, pol);
2846 if (mpfr_nan_p(result.backend().data()))
2847 return policies::raise_evaluation_error("erfc<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2848 return result;
2849 }
2850 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2851 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)
2852 {
2853 return erfc(arg, policies::policy<>());
2854 }
2855
2856 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2857 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)
2858 {
2859 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2860
2861 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2862 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
2863 if (mpfr_inf_p(result.backend().data()))
2864 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("expm1<%1%>(%1%)", nullptr, pol);
2865 if (mpfr_nan_p(result.backend().data()))
2866 return policies::raise_evaluation_error("expm1<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2867 return result;
2868 }
2869 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2870 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2871 {
2872 return expm1(arg, policies::policy<>());
2873 }
2874
2875 #ifdef BOOST_MP_MATH_AVAILABLE
2876 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2877 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)
2878 {
2879 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2880 (void)precision_guard;
2881
2882 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2883 if (arg > 0)
2884 {
2885 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2886 if (sign)
2887 *sign = 1;
2888 }
2889 else
2890 {
2891 if (floor(arg) == arg)
2892 return policies::raise_pole_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >(
2893 "lgamma<%1%>", "Evaluation of lgamma at a negative integer %1%.", arg, pol);
2894
2895 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> t = detail::sinpx(arg);
2896 arg = -arg;
2897 if (t < 0)
2898 {
2899 t = -t;
2900 }
2901 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);
2902 if (sign)
2903 {
2904 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> phase = 1 - arg;
2905 phase = floor(phase) / 2;
2906 if (floor(phase) == phase)
2907 *sign = -1;
2908 else
2909 *sign = 1;
2910 }
2911 }
2912 if (mpfr_inf_p(result.backend().data()))
2913 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("lgamma<%1%>(%1%)", nullptr, pol);
2914 if (mpfr_nan_p(result.backend().data()))
2915 return policies::raise_evaluation_error("lgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2916 return result;
2917 }
2918 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2919 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)
2920 {
2921 return lgamma(arg, sign, policies::policy<>());
2922 }
2923 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2924 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)
2925 {
2926 return lgamma(arg, 0, pol);
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)
2930 {
2931 return lgamma(arg, 0, policies::policy<>());
2932 }
2933 #endif
2934
2935 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2936 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)
2937 {
2938 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2939
2940 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2941 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2942 if (mpfr_inf_p(result.backend().data()))
2943 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("tgamma<%1%>(%1%)", nullptr, pol);
2944 if (mpfr_nan_p(result.backend().data()))
2945 return policies::raise_evaluation_error("tgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2946 return result;
2947 }
2948 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2949 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)
2950 {
2951 return tgamma(arg, policies::policy<>());
2952 }
2953
2954 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2955 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)
2956 {
2957 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2958
2959 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2960 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
2961 if (mpfr_inf_p(result.backend().data()))
2962 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);
2963 if (mpfr_nan_p(result.backend().data()))
2964 return policies::raise_evaluation_error("log1p<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2965 return result;
2966 }
2967 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2968 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)
2969 {
2970 return log1p(arg, policies::policy<>());
2971 }
2972
2973 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2974 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)
2975 {
2976 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2977
2978 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2979 mpfr_rec_sqrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2980 if (mpfr_inf_p(result.backend().data()))
2981 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("rsqrt<%1%>(%1%)", nullptr, pol);
2982 if (mpfr_nan_p(result.backend().data()))
2983 return policies::raise_evaluation_error("rsqrt<%1%>(%1%)", "Negative argument, result is a NaN", result, pol);
2984 return result;
2985 }
2986 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2987 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)
2988 {
2989 return rsqrt(arg, policies::policy<>());
2990 }
2991
2992
2993
2994
2995 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2996 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)
2997 {
2998 return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
2999 }
3000 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3001 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)
3002 {
3003 return asinh(arg, policies::policy<>());
3004 }
3005
3006 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3007 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)
3008 {
3009 return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3010 }
3011 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3012 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)
3013 {
3014 return acosh(arg, policies::policy<>());
3015 }
3016
3017 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3018 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)
3019 {
3020 return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3021 }
3022 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3023 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)
3024 {
3025 return atanh(arg, policies::policy<>());
3026 }
3027
3028 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3029 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)
3030 {
3031 return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3032 }
3033 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3034 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)
3035 {
3036 return cbrt(arg, policies::policy<>());
3037 }
3038
3039 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3040 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)
3041 {
3042 return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3043 }
3044 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3045 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)
3046 {
3047 return erf(arg, policies::policy<>());
3048 }
3049
3050 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3051 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)
3052 {
3053 return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3054 }
3055 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3056 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)
3057 {
3058 return erfc(arg, policies::policy<>());
3059 }
3060
3061 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3062 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)
3063 {
3064 return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3065 }
3066 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3067 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)
3068 {
3069 return expm1(arg, policies::policy<>());
3070 }
3071
3072 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3073 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)
3074 {
3075 return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
3076 }
3077 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3078 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)
3079 {
3080 return lgamma(arg, sign, policies::policy<>());
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(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3084 {
3085 return lgamma(arg, 0, pol);
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)
3089 {
3090 return lgamma(arg, 0, policies::policy<>());
3091 }
3092
3093 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3094 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)
3095 {
3096 return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3097 }
3098 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3099 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)
3100 {
3101 return tgamma(arg, policies::policy<>());
3102 }
3103
3104 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3105 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)
3106 {
3107 return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3108 }
3109 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3110 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)
3111 {
3112 return log1p(arg, policies::policy<>());
3113 }
3114
3115 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3116 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)
3117 {
3118 return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3119 }
3120 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3121 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)
3122 {
3123 return rsqrt(arg, policies::policy<>());
3124 }
3125
3126
3127
3128
3129 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3130 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)
3131 {
3132 return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3133 }
3134 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3135 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)
3136 {
3137 return asinh(arg, policies::policy<>());
3138 }
3139
3140 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3141 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)
3142 {
3143 return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3144 }
3145 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3146 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)
3147 {
3148 return acosh(arg, policies::policy<>());
3149 }
3150
3151 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3152 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)
3153 {
3154 return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3155 }
3156 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3157 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)
3158 {
3159 return atanh(arg, policies::policy<>());
3160 }
3161
3162 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3163 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)
3164 {
3165 return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3166 }
3167 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3168 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)
3169 {
3170 return cbrt(arg, policies::policy<>());
3171 }
3172
3173 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3174 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)
3175 {
3176 return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3177 }
3178 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3179 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)
3180 {
3181 return erf(arg, policies::policy<>());
3182 }
3183
3184 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3185 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)
3186 {
3187 return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3188 }
3189 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3190 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)
3191 {
3192 return erfc(arg, policies::policy<>());
3193 }
3194
3195 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3196 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)
3197 {
3198 return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3199 }
3200 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3201 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)
3202 {
3203 return expm1(arg, policies::policy<>());
3204 }
3205
3206 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3207 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)
3208 {
3209 return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
3210 }
3211 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3212 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)
3213 {
3214 return lgamma(arg, sign, policies::policy<>());
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(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3218 {
3219 return lgamma(arg, 0, pol);
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)
3223 {
3224 return lgamma(arg, 0, policies::policy<>());
3225 }
3226
3227 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3228 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)
3229 {
3230 return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3231 }
3232 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3233 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)
3234 {
3235 return tgamma(arg, policies::policy<>());
3236 }
3237
3238 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3239 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)
3240 {
3241 return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3242 }
3243 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3244 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)
3245 {
3246 return log1p(arg, policies::policy<>());
3247 }
3248
3249 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3250 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)
3251 {
3252 return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3253 }
3254 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3255 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)
3256 {
3257 return rsqrt(arg, policies::policy<>());
3258 }
3259
3260 }
3261
3262 }
3263
3264 namespace Eigen
3265 {
3266
3267 template <class B1, class B2>
3268 struct NumTraitsImp;
3269
3270 template <boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3271 struct NumTraitsImp<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>
3272 {
3273 using self_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>;
3274 using Real = typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type;
3275 using NonInteger = self_type;
3276 using Literal = double;
3277 using Nested = self_type;
3278 enum
3279 {
3280 IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
3281 IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
3282 ReadCost = 1,
3283 AddCost = 4,
3284 MulCost = 8,
3285 IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
3286 RequireInitialization = 1,
3287 };
3288 static Real epsilon()
3289 {
3290 #ifdef BOOST_MP_MATH_AVAILABLE
3291 return boost::math::tools::epsilon< boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3292 #else
3293 self_type result{1};
3294 mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<self_type>::digits - 1, GMP_RNDN);
3295 return result;
3296 #endif
3297 }
3298 static Real dummy_precision()
3299 {
3300 return 1000 * epsilon();
3301 }
3302 static Real highest()
3303 {
3304 #ifdef BOOST_MP_MATH_AVAILABLE
3305 return boost::math::tools::max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3306 #else
3307 self_type value(0.5);
3308 mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
3309 return value;
3310 #endif
3311 }
3312 static Real lowest()
3313 {
3314 #ifdef BOOST_MP_MATH_AVAILABLE
3315 return boost::math::tools::min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3316 #else
3317 return -(highest)();
3318 #endif
3319 }
3320 static int digits10()
3321 {
3322 return Real::thread_default_precision();
3323 }
3324 static int digits()
3325 {
3326 return boost::math::tools::digits<Real>();
3327 }
3328 static int min_exponent()
3329 {
3330 return static_cast<int>(mpfr_get_emin());
3331 }
3332 static int max_exponent()
3333 {
3334 return static_cast<int>(mpfr_get_emax());
3335 }
3336 static Real infinity()
3337 {
3338 return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::infinity();
3339 }
3340 static Real quiet_NaN()
3341 {
3342 return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::quiet_NaN();
3343 }
3344 };
3345
3346 }
3347
3348 namespace std {
3349
3350
3351
3352
3353 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3354 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
3355 {
3356 using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
3357
3358 static number_type get_min()
3359 {
3360 number_type result{0.5};
3361 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
3362 return result;
3363 }
3364 static number_type get_max()
3365 {
3366 number_type result{0.5};
3367 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
3368 return result;
3369 }
3370 static number_type get_eps()
3371 {
3372 number_type result{1};
3373 mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
3374 return result;
3375 }
3376
3377 public:
3378 static constexpr bool is_specialized = true;
3379 static number_type(min)()
3380 {
3381 static number_type value{get_min()};
3382 return value;
3383 }
3384 static number_type(max)()
3385 {
3386 static number_type value{get_max()};
3387 return value;
3388 }
3389 static constexpr number_type lowest()
3390 {
3391 return -(max)();
3392 }
3393 static constexpr int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
3394 static constexpr int digits10 = Digits10;
3395
3396 static constexpr int max_digits10 = static_cast<int>(boost::multiprecision::detail::calc_max_digits10<static_cast<unsigned>(digits)>::value);
3397 static constexpr bool is_signed = true;
3398 static constexpr bool is_integer = false;
3399 static constexpr bool is_exact = false;
3400 static constexpr int radix = 2;
3401 static number_type epsilon()
3402 {
3403 static number_type value{get_eps()};
3404 return value;
3405 }
3406
3407 static number_type round_error()
3408 {
3409
3410 return 0.5;
3411 }
3412 static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
3413 static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
3414 static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
3415 static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
3416 static constexpr bool has_infinity = true;
3417 static constexpr bool has_quiet_NaN = true;
3418 static constexpr bool has_signaling_NaN = false;
3419 static constexpr float_denorm_style has_denorm = denorm_absent;
3420 static constexpr bool has_denorm_loss = false;
3421 static number_type infinity()
3422 {
3423 number_type value;
3424 mpfr_set_inf(value.backend().data(), 1);
3425 return value;
3426 }
3427 static number_type quiet_NaN()
3428 {
3429 number_type value;
3430 mpfr_set_nan(value.backend().data());
3431 return value;
3432 }
3433 static constexpr number_type signaling_NaN()
3434 {
3435 return number_type(0);
3436 }
3437 static constexpr number_type denorm_min() { return (min)(); }
3438 static constexpr bool is_iec559 = false;
3439 static constexpr bool is_bounded = true;
3440 static constexpr bool is_modulo = false;
3441 static constexpr bool traps = true;
3442 static constexpr bool tinyness_before = false;
3443 static constexpr float_round_style round_style = round_to_nearest;
3444 };
3445
3446 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3447 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
3448 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3449 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
3450 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3451 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
3452 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3453 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
3454 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3455 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
3456 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3457 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
3458 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3459 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
3460 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3461 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
3462 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3463 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
3464 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3465 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
3466 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3467 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
3468 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3469 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
3470 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3471 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
3472 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3473 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
3474 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3475 constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
3476 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3477 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
3478 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3479 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
3480 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3481 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
3482 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3483 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
3484 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3485 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
3486 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3487 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
3488 template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3489 constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
3490
3491 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3492 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
3493 {
3494 using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates>;
3495
3496 public:
3497 static constexpr bool is_specialized = false;
3498 static number_type(min)()
3499 {
3500 number_type value(0.5);
3501 mpfr_div_2exp(value.backend().data(), value.backend().data(), -mpfr_get_emin(), GMP_RNDN);
3502 return value;
3503 }
3504 static number_type(max)()
3505 {
3506 number_type value(0.5);
3507 mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
3508 return value;
3509 }
3510 static number_type lowest()
3511 {
3512 return -(max)();
3513 }
3514 static constexpr int digits = INT_MAX;
3515 static constexpr int digits10 = INT_MAX;
3516 static constexpr int max_digits10 = INT_MAX;
3517 static constexpr bool is_signed = true;
3518 static constexpr bool is_integer = false;
3519 static constexpr bool is_exact = false;
3520 static constexpr int radix = 2;
3521 static number_type epsilon()
3522 {
3523 number_type value(1);
3524 mpfr_div_2exp(value.backend().data(), value.backend().data(), boost::multiprecision::detail::digits10_2_2(number_type::thread_default_precision()) - 1, GMP_RNDN);
3525 return value;
3526 }
3527 static number_type round_error()
3528 {
3529 return 0.5;
3530 }
3531 static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
3532 static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
3533 static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
3534 static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
3535 static constexpr bool has_infinity = true;
3536 static constexpr bool has_quiet_NaN = true;
3537 static constexpr bool has_signaling_NaN = false;
3538 static constexpr float_denorm_style has_denorm = denorm_absent;
3539 static constexpr bool has_denorm_loss = false;
3540 static number_type infinity()
3541 {
3542 number_type value;
3543 mpfr_set_inf(value.backend().data(), 1);
3544 return value;
3545 }
3546 static number_type quiet_NaN()
3547 {
3548 number_type value;
3549 mpfr_set_nan(value.backend().data());
3550 return value;
3551 }
3552 static number_type signaling_NaN() { return number_type(0); }
3553 static number_type denorm_min() { return (min)(); }
3554 static constexpr bool is_iec559 = false;
3555 static constexpr bool is_bounded = true;
3556 static constexpr bool is_modulo = false;
3557 static constexpr bool traps = false;
3558 static constexpr bool tinyness_before = false;
3559 static constexpr float_round_style round_style = round_toward_zero;
3560 };
3561
3562 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3563 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
3564 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3565 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
3566 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3567 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
3568 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3569 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
3570 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3571 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
3572 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3573 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
3574 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3575 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
3576 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3577 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
3578 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3579 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
3580 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3581 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
3582 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3583 constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
3584 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3585 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
3586 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3587 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
3588 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3589 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
3590 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3591 constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
3592 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3593 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
3594 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3595 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
3596 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3597 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
3598 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3599 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
3600 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3601 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
3602 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3603 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
3604 template <boost::multiprecision::expression_template_option ExpressionTemplates>
3605 constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;
3606
3607 }
3608 #endif