File indexing completed on 2025-01-18 09:42:32
0001
0002
0003
0004
0005
0006 #ifndef BOOST_MP_MPC_HPP
0007 #define BOOST_MP_MPC_HPP
0008
0009 #include <cstdint>
0010 #include <boost/multiprecision/detail/standalone_config.hpp>
0011 #include <boost/multiprecision/detail/fpclassify.hpp>
0012 #include <boost/multiprecision/number.hpp>
0013 #include <boost/multiprecision/detail/digits.hpp>
0014 #include <boost/multiprecision/detail/atomic.hpp>
0015 #include <boost/multiprecision/traits/is_variable_precision.hpp>
0016 #include <boost/multiprecision/mpfr.hpp>
0017 #include <boost/multiprecision/detail/hash.hpp>
0018 #include <boost/multiprecision/detail/no_exceptions_support.hpp>
0019 #include <boost/multiprecision/detail/assert.hpp>
0020 #include <mpc.h>
0021 #include <cmath>
0022 #include <algorithm>
0023 #include <complex>
0024
0025 #ifndef BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION
0026 #define BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION 20
0027 #endif
0028
0029 namespace boost {
0030 namespace multiprecision {
0031
0032 template <unsigned digits10>
0033 struct number_category<backends::mpc_complex_backend<digits10> > : public std::integral_constant<int, number_kind_complex>
0034 {};
0035
0036 namespace backends {
0037
0038 namespace detail {
0039
0040 inline void mpc_copy_precision(mpc_t dest, const mpc_t src)
0041 {
0042 mpfr_prec_t p_dest = mpc_get_prec(dest);
0043 mpfr_prec_t p_src = mpc_get_prec(src);
0044 if (p_dest != p_src)
0045 mpc_set_prec(dest, p_src);
0046 }
0047 inline void mpc_copy_precision(mpc_t dest, const mpc_t src1, const mpc_t src2)
0048 {
0049 mpfr_prec_t p_dest = mpc_get_prec(dest);
0050 mpfr_prec_t p_src1 = mpc_get_prec(src1);
0051 mpfr_prec_t p_src2 = mpc_get_prec(src2);
0052 if (p_src2 > p_src1)
0053 p_src1 = p_src2;
0054 if (p_dest != p_src1)
0055 mpc_set_prec(dest, p_src1);
0056 }
0057
0058 template <unsigned digits10>
0059 struct mpc_complex_imp
0060 {
0061 #ifdef BOOST_HAS_LONG_LONG
0062 using signed_types = std::tuple<long, long long> ;
0063 using unsigned_types = std::tuple<unsigned long, unsigned long long>;
0064 #else
0065 using signed_types = std::tuple<long> ;
0066 using unsigned_types = std::tuple<unsigned long>;
0067 #endif
0068 using float_types = std::tuple<double, long double>;
0069 using exponent_type = long ;
0070
0071 mpc_complex_imp()
0072 {
0073 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0074 mpc_set_ui(m_data, 0u, GMP_RNDN);
0075 }
0076 mpc_complex_imp(unsigned digits2)
0077 {
0078 mpc_init2(m_data, digits2);
0079 mpc_set_ui(m_data, 0u, GMP_RNDN);
0080 }
0081
0082 mpc_complex_imp(const mpc_complex_imp& o)
0083 {
0084 mpc_init2(m_data, preserve_source_precision() ? mpc_get_prec(o.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
0085 if (o.m_data[0].re[0]._mpfr_d)
0086 mpc_set(m_data, o.m_data, GMP_RNDN);
0087 }
0088
0089 mpc_complex_imp(mpc_complex_imp&& o) noexcept
0090 {
0091 mpfr_prec_t binary_default_precision = boost::multiprecision::detail::digits10_2_2(get_default_precision());
0092 if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpc_get_prec(o.data()) == binary_default_precision))
0093 {
0094 m_data[0] = o.m_data[0];
0095 o.m_data[0].re[0]._mpfr_d = nullptr;
0096 }
0097 else
0098 {
0099
0100 mpc_init2(m_data, binary_default_precision);
0101 if (o.m_data[0].re[0]._mpfr_d)
0102 mpc_set(m_data, o.m_data, GMP_RNDN);
0103 }
0104 }
0105 mpc_complex_imp& operator=(const mpc_complex_imp& o)
0106 {
0107 if ((o.m_data[0].re[0]._mpfr_d) && (this != &o))
0108 {
0109 if (m_data[0].re[0]._mpfr_d == nullptr)
0110 mpc_init2(m_data, preserve_source_precision() ? mpc_get_prec(o.m_data) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
0111 else if (preserve_source_precision() && (mpc_get_prec(o.data()) != mpc_get_prec(data())))
0112 {
0113 mpc_set_prec(m_data, mpc_get_prec(o.m_data));
0114 }
0115 mpc_set(m_data, o.m_data, GMP_RNDN);
0116 }
0117 return *this;
0118 }
0119
0120 mpc_complex_imp& operator=(mpc_complex_imp&& o) noexcept
0121 {
0122 if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpc_get_prec(o.data()) == mpc_get_prec(data())))
0123 mpc_swap(m_data, o.m_data);
0124 else
0125 *this = static_cast<const mpc_complex_imp&>(o);
0126 return *this;
0127 }
0128 #ifdef BOOST_HAS_LONG_LONG
0129 #ifdef _MPFR_H_HAVE_INTMAX_T
0130 mpc_complex_imp& operator=(unsigned long long i)
0131 {
0132 if (m_data[0].re[0]._mpfr_d == nullptr)
0133 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0134 mpc_set_uj(data(), i, GMP_RNDN);
0135 return *this;
0136 }
0137 mpc_complex_imp& operator=(long long i)
0138 {
0139 if (m_data[0].re[0]._mpfr_d == nullptr)
0140 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0141 mpc_set_sj(data(), i, GMP_RNDN);
0142 return *this;
0143 }
0144 #else
0145 mpc_complex_imp& operator=(unsigned long long i)
0146 {
0147 mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data));
0148 f = i;
0149 mpc_set_fr(this->data(), f.data(), GMP_RNDN);
0150 return *this;
0151 }
0152 mpc_complex_imp& operator=(long long i)
0153 {
0154 mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data));
0155 f = i;
0156 mpc_set_fr(this->data(), f.data(), GMP_RNDN);
0157 return *this;
0158 }
0159 #endif
0160 #endif
0161 mpc_complex_imp& operator=(unsigned long i)
0162 {
0163 if (m_data[0].re[0]._mpfr_d == nullptr)
0164 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0165 mpc_set_ui(m_data, i, GMP_RNDN);
0166 return *this;
0167 }
0168 mpc_complex_imp& operator=(long i)
0169 {
0170 if (m_data[0].re[0]._mpfr_d == nullptr)
0171 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0172 mpc_set_si(m_data, i, GMP_RNDN);
0173 return *this;
0174 }
0175 mpc_complex_imp& operator=(double d)
0176 {
0177 if (m_data[0].re[0]._mpfr_d == nullptr)
0178 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0179 mpc_set_d(m_data, d, GMP_RNDN);
0180 return *this;
0181 }
0182 mpc_complex_imp& operator=(long double d)
0183 {
0184 if (m_data[0].re[0]._mpfr_d == nullptr)
0185 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0186 mpc_set_ld(m_data, d, GMP_RNDN);
0187 return *this;
0188 }
0189 mpc_complex_imp& operator=(mpz_t i)
0190 {
0191 if (m_data[0].re[0]._mpfr_d == nullptr)
0192 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0193 mpc_set_z(m_data, i, GMP_RNDN);
0194 return *this;
0195 }
0196 mpc_complex_imp& operator=(gmp_int i)
0197 {
0198 if (m_data[0].re[0]._mpfr_d == nullptr)
0199 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0200 mpc_set_z(m_data, i.data(), GMP_RNDN);
0201 return *this;
0202 }
0203 #ifdef BOOST_HAS_INT128
0204 mpc_complex_imp& operator=(int128_type val)
0205 {
0206 gmp_int i;
0207 i = val;
0208 return *this = i.data();
0209 }
0210 mpc_complex_imp& operator=(uint128_type val)
0211 {
0212 gmp_int i;
0213 i = val;
0214 return *this = i.data();
0215 }
0216 #endif
0217 #ifdef BOOST_HAS_FLOAT128
0218 mpc_complex_imp& operator=(float128_type val)
0219 {
0220 mpfr_float_backend<digits10> f;
0221 f = val;
0222 mpc_set_fr(this->m_data, f.data(), GMP_RNDN);
0223 return *this;
0224 }
0225 #endif
0226
0227 mpc_complex_imp& operator=(const char* s)
0228 {
0229 using default_ops::eval_fpclassify;
0230
0231 if (m_data[0].re[0]._mpfr_d == nullptr)
0232 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
0233
0234 mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data));
0235
0236 if (s && (*s == '('))
0237 {
0238 std::string part;
0239 const char* p = ++s;
0240 while (*p && (*p != ',') && (*p != ')'))
0241 ++p;
0242 part.assign(s, p);
0243 if (part.size())
0244 a = part.c_str();
0245 else
0246 a = 0uL;
0247 s = p;
0248 if (*p && (*p != ')'))
0249 {
0250 ++p;
0251 while (*p && (*p != ')'))
0252 ++p;
0253 part.assign(s + 1, p);
0254 }
0255 else
0256 part.erase();
0257 if (part.size())
0258 b = part.c_str();
0259 else
0260 b = 0uL;
0261 }
0262 else
0263 {
0264 a = s;
0265 b = 0uL;
0266 }
0267
0268 if (eval_fpclassify(a) == static_cast<int>(FP_NAN))
0269 {
0270 mpc_set_fr(this->data(), a.data(), GMP_RNDN);
0271 }
0272 else if (eval_fpclassify(b) == static_cast<int>(FP_NAN))
0273 {
0274 mpc_set_fr(this->data(), b.data(), GMP_RNDN);
0275 }
0276 else
0277 {
0278 mpc_set_fr_fr(m_data, a.data(), b.data(), GMP_RNDN);
0279 }
0280 return *this;
0281 }
0282 void swap(mpc_complex_imp& o) noexcept
0283 {
0284 mpc_swap(m_data, o.m_data);
0285 }
0286 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
0287 {
0288 BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d);
0289
0290 mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data));
0291
0292 mpc_real(a.data(), m_data, GMP_RNDN);
0293 mpc_imag(b.data(), m_data, GMP_RNDN);
0294
0295 if (eval_is_zero(b))
0296 return a.str(digits, f);
0297
0298 return "(" + a.str(digits, f) + "," + b.str(digits, f) + ")";
0299 }
0300 ~mpc_complex_imp() noexcept
0301 {
0302 if (m_data[0].re[0]._mpfr_d)
0303 mpc_clear(m_data);
0304 }
0305 void negate() noexcept
0306 {
0307 BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d);
0308 mpc_neg(m_data, m_data, GMP_RNDN);
0309 }
0310 int compare(const mpc_complex_imp& o) const noexcept
0311 {
0312 BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d);
0313 return mpc_cmp(m_data, o.m_data);
0314 }
0315 int compare(const mpc_complex_backend<digits10>& o) const noexcept
0316 {
0317 BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d);
0318 return mpc_cmp(m_data, o.data());
0319 }
0320 int compare(long int i) const noexcept
0321 {
0322 BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d);
0323 return mpc_cmp_si(m_data, i);
0324 }
0325 int compare(unsigned long int i) const noexcept
0326 {
0327 BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d);
0328 constexpr const unsigned long int max_val = (std::numeric_limits<long>::max)();
0329 if (i > max_val)
0330 {
0331 mpc_complex_imp d(mpc_get_prec(m_data));
0332 d = i;
0333 return compare(d);
0334 }
0335 return mpc_cmp_si(m_data, static_cast<long>(i));
0336 }
0337 template <class V>
0338 int compare(const V& v) const noexcept
0339 {
0340 mpc_complex_imp d(mpc_get_prec(m_data));
0341 d = v;
0342 return compare(d);
0343 }
0344 mpc_t& data() noexcept
0345 {
0346 BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d);
0347 return m_data;
0348 }
0349 const mpc_t& data() const noexcept
0350 {
0351 BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d);
0352 return m_data;
0353 }
0354
0355 protected:
0356 mpc_t m_data;
0357 static boost::multiprecision::detail::precision_type& get_global_default_precision() noexcept
0358 {
0359 static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION);
0360 return val;
0361 }
0362 static unsigned& get_default_precision() noexcept
0363 {
0364 static BOOST_MP_THREAD_LOCAL unsigned val(get_global_default_precision());
0365 return val;
0366 }
0367 #ifndef BOOST_MT_NO_ATOMIC_INT
0368 static std::atomic<variable_precision_options>& get_global_default_options() noexcept
0369 #else
0370 static variable_precision_options& get_global_default_options() noexcept
0371 #endif
0372 {
0373 #ifndef BOOST_MT_NO_ATOMIC_INT
0374 static std::atomic<variable_precision_options> val{variable_precision_options::preserve_related_precision};
0375 #else
0376 static variable_precision_options val{variable_precision_options::preserve_related_precision};
0377 #endif
0378 return val;
0379 }
0380 static variable_precision_options& get_default_options() noexcept
0381 {
0382 static BOOST_MP_THREAD_LOCAL variable_precision_options val(get_global_default_options());
0383 return val;
0384 }
0385 static bool preserve_source_precision() noexcept
0386 {
0387 return get_default_options() >= variable_precision_options::preserve_source_precision;
0388 }
0389 static bool preserve_component_precision() noexcept
0390 {
0391 return get_default_options() >= variable_precision_options::preserve_component_precision;
0392 }
0393 static bool preserve_related_precision() noexcept
0394 {
0395 return get_default_options() >= variable_precision_options::preserve_related_precision;
0396 }
0397 static bool preserve_all_precision() noexcept
0398 {
0399 return get_default_options() >= variable_precision_options::preserve_all_precision;
0400 }
0401 };
0402
0403 }
0404
0405 template <unsigned digits10>
0406 struct mpc_complex_backend : public detail::mpc_complex_imp<digits10>
0407 {
0408 mpc_complex_backend() : detail::mpc_complex_imp<digits10>() {}
0409 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<digits10>(o) {}
0410
0411 mpc_complex_backend(mpc_complex_backend&& o) : detail::mpc_complex_imp<digits10>(static_cast<detail::mpc_complex_imp<digits10>&&>(o))
0412 {}
0413 template <unsigned D>
0414 mpc_complex_backend(const mpc_complex_backend<D>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
0415 : detail::mpc_complex_imp<digits10>()
0416 {
0417 mpc_set(this->m_data, val.data(), GMP_RNDN);
0418 }
0419 template <unsigned D>
0420 explicit mpc_complex_backend(const mpc_complex_backend<D>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
0421 : detail::mpc_complex_imp<digits10>()
0422 {
0423 mpc_set(this->m_data, val.data(), GMP_RNDN);
0424 }
0425 mpc_complex_backend(const mpc_t val)
0426 : detail::mpc_complex_imp<digits10>()
0427 {
0428 mpc_set(this->m_data, val, GMP_RNDN);
0429 }
0430 mpc_complex_backend(const std::complex<float>& val)
0431 : detail::mpc_complex_imp<digits10>()
0432 {
0433 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
0434 }
0435 mpc_complex_backend(const std::complex<double>& val)
0436 : detail::mpc_complex_imp<digits10>()
0437 {
0438 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
0439 }
0440 mpc_complex_backend(const std::complex<long double>& val)
0441 : detail::mpc_complex_imp<digits10>()
0442 {
0443 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
0444 }
0445 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<digits10>()
0446 {
0447 mpc_set_z(this->m_data, val, GMP_RNDN);
0448 }
0449 mpc_complex_backend& operator=(mpz_srcptr val)
0450 {
0451 mpc_set_z(this->m_data, val, GMP_RNDN);
0452 return *this;
0453 }
0454 mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<digits10>()
0455 {
0456 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
0457 }
0458 mpc_complex_backend& operator=(gmp_int const& val)
0459 {
0460 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
0461 return *this;
0462 }
0463 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<digits10>()
0464 {
0465 mpc_set_f(this->m_data, val, GMP_RNDN);
0466 }
0467 mpc_complex_backend& operator=(mpf_srcptr val)
0468 {
0469 mpc_set_f(this->m_data, val, GMP_RNDN);
0470 return *this;
0471 }
0472 template <unsigned D10>
0473 mpc_complex_backend(gmp_float<D10> const& val) : detail::mpc_complex_imp<digits10>()
0474 {
0475 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
0476 }
0477 template <unsigned D10>
0478 mpc_complex_backend& operator=(gmp_float<D10> const& val)
0479 {
0480 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
0481 return *this;
0482 }
0483 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<digits10>()
0484 {
0485 mpc_set_q(this->m_data, val, GMP_RNDN);
0486 }
0487 mpc_complex_backend& operator=(mpq_srcptr val)
0488 {
0489 mpc_set_q(this->m_data, val, GMP_RNDN);
0490 return *this;
0491 }
0492 mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<digits10>()
0493 {
0494 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
0495 }
0496 mpc_complex_backend& operator=(gmp_rational const& val)
0497 {
0498 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
0499 return *this;
0500 }
0501 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<digits10>()
0502 {
0503 mpc_set_fr(this->m_data, val, GMP_RNDN);
0504 }
0505 mpc_complex_backend& operator=(mpfr_srcptr val)
0506 {
0507 mpc_set_fr(this->m_data, val, GMP_RNDN);
0508 return *this;
0509 }
0510 template <unsigned D10, mpfr_allocation_type AllocationType>
0511 mpc_complex_backend(mpfr_float_backend<D10, AllocationType> const& val, typename std::enable_if<D10 <= digits10>::type* = nullptr) : detail::mpc_complex_imp<digits10>()
0512 {
0513 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
0514 }
0515 template <unsigned D10, mpfr_allocation_type AllocationType>
0516 explicit mpc_complex_backend(mpfr_float_backend<D10, AllocationType> const& val, typename std::enable_if<!(D10 <= digits10)>::type* = nullptr) : detail::mpc_complex_imp<digits10>()
0517 {
0518 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
0519 }
0520 template <unsigned D10, mpfr_allocation_type AllocationType>
0521 mpc_complex_backend& operator=(mpfr_float_backend<D10, AllocationType> const& val)
0522 {
0523 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
0524 return *this;
0525 }
0526 mpc_complex_backend& operator=(const mpc_complex_backend& o)
0527 {
0528 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10> const&>(o);
0529 return *this;
0530 }
0531
0532 mpc_complex_backend& operator=(mpc_complex_backend&& o) noexcept
0533 {
0534 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10>&&>(o);
0535 return *this;
0536 }
0537 template <class V>
0538 typename std::enable_if<std::is_assignable<detail::mpc_complex_imp<digits10>, V>::value, mpc_complex_backend&>::type operator=(const V& v)
0539 {
0540 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = v;
0541 return *this;
0542 }
0543 mpc_complex_backend& operator=(const mpc_t val)
0544 {
0545 mpc_set(this->m_data, val, GMP_RNDN);
0546 return *this;
0547 }
0548 mpc_complex_backend& operator=(const std::complex<float>& val)
0549 {
0550 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
0551 return *this;
0552 }
0553 mpc_complex_backend& operator=(const std::complex<double>& val)
0554 {
0555 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
0556 return *this;
0557 }
0558 mpc_complex_backend& operator=(const std::complex<long double>& val)
0559 {
0560 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
0561 return *this;
0562 }
0563
0564 template <unsigned D>
0565 mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
0566 {
0567 mpc_set(this->m_data, val.data(), GMP_RNDN);
0568 return *this;
0569 }
0570 };
0571
0572 template <>
0573 struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0>
0574 {
0575 mpc_complex_backend() : detail::mpc_complex_imp<0>() {}
0576 mpc_complex_backend(const mpc_t val)
0577 : detail::mpc_complex_imp<0>(mpc_get_prec(val))
0578 {
0579 mpc_set(this->m_data, val, GMP_RNDN);
0580 }
0581 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<0>(o) {}
0582
0583 mpc_complex_backend(mpc_complex_backend&& o) noexcept : detail::mpc_complex_imp<0>(static_cast<detail::mpc_complex_imp<0>&&>(o))
0584 {}
0585 mpc_complex_backend(const mpc_complex_backend& o, unsigned digits10)
0586 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
0587 {
0588 mpc_set(this->m_data, o.data(), GMP_RNDN);
0589 }
0590 template <unsigned D>
0591 mpc_complex_backend(const mpc_complex_backend<D>& val)
0592 : detail::mpc_complex_imp<0>(preserve_related_precision() ? mpc_get_prec(val.data()) : multiprecision::detail::digits10_2_2(get_default_precision()))
0593 {
0594 mpc_set(this->m_data, val.data(), GMP_RNDN);
0595 }
0596 template <unsigned D>
0597 mpc_complex_backend(const mpfr_float_backend<D>& val)
0598 : detail::mpc_complex_imp<0>((D == 0 ? this->preserve_component_precision() : this->preserve_related_precision()) ? mpfr_get_prec(val.data()) : multiprecision::detail::digits10_2_2(this->get_default_precision()))
0599 {
0600 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
0601 }
0602 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<0>()
0603 {
0604 mpc_set_z(this->m_data, val, GMP_RNDN);
0605 }
0606 mpc_complex_backend& operator=(mpz_srcptr val)
0607 {
0608 mpc_set_z(this->m_data, val, GMP_RNDN);
0609 return *this;
0610 }
0611 mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<0>(preserve_all_precision() ? used_gmp_int_bits(val) : boost::multiprecision::detail::digits10_2_2(thread_default_precision()))
0612 {
0613 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
0614 }
0615 mpc_complex_backend& operator=(gmp_int const& val)
0616 {
0617 if (this->m_data[0].im->_mpfr_d == nullptr)
0618 {
0619 unsigned requested_precision = this->thread_default_precision();
0620 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
0621 {
0622 unsigned d2 = used_gmp_int_bits(val);
0623 unsigned d10 = 1 + multiprecision::detail::digits2_2_10(d2);
0624 if (d10 > requested_precision)
0625 requested_precision = d10;
0626 }
0627 mpc_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
0628 }
0629 else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
0630 {
0631 unsigned requested_precision = this->thread_default_precision();
0632 unsigned d2 = used_gmp_int_bits(val);
0633 unsigned d10 = 1 + multiprecision::detail::digits2_2_10(d2);
0634 if (d10 > requested_precision)
0635 this->precision(d10);
0636 }
0637 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
0638 return *this;
0639 }
0640 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val))
0641 {
0642 mpc_set_f(this->m_data, val, GMP_RNDN);
0643 }
0644 mpc_complex_backend& operator=(mpf_srcptr val)
0645 {
0646 if ((mp_bitcnt_t)mpc_get_prec(data()) != mpf_get_prec(val))
0647 {
0648 mpc_complex_backend t(val);
0649 t.swap(*this);
0650 }
0651 else
0652 mpc_set_f(this->m_data, val, GMP_RNDN);
0653 return *this;
0654 }
0655 template <unsigned digits10>
0656 mpc_complex_backend(gmp_float<digits10> const& val) : detail::mpc_complex_imp<0>(preserve_all_precision() ? (unsigned)mpf_get_prec(val.data()) : multiprecision::detail::digits10_2_2(get_default_precision()))
0657 {
0658 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
0659 }
0660 template <unsigned digits10>
0661 mpc_complex_backend& operator=(gmp_float<digits10> const& val)
0662 {
0663 if (preserve_all_precision() && (mpc_get_prec(data()) != (mpfr_prec_t)mpf_get_prec(val.data())))
0664 {
0665 mpc_complex_backend t(val);
0666 t.swap(*this);
0667 }
0668 else
0669 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
0670 return *this;
0671 }
0672 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<0>()
0673 {
0674 mpc_set_q(this->m_data, val, GMP_RNDN);
0675 }
0676 mpc_complex_backend& operator=(mpq_srcptr val)
0677 {
0678 mpc_set_q(this->m_data, val, GMP_RNDN);
0679 return *this;
0680 }
0681 mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<0>(preserve_all_precision() ? used_gmp_rational_bits(val) : boost::multiprecision::detail::digits10_2_2(thread_default_precision()))
0682 {
0683 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
0684 }
0685 mpc_complex_backend& operator=(gmp_rational const& val)
0686 {
0687 if (this->m_data[0].im->_mpfr_d == nullptr)
0688 {
0689 unsigned requested_precision = this->get_default_precision();
0690 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
0691 {
0692 unsigned d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val));
0693 if (d10 > requested_precision)
0694 requested_precision = d10;
0695 }
0696 mpc_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
0697 }
0698 else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
0699 {
0700 unsigned requested_precision = this->get_default_precision();
0701 unsigned d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val));
0702 if (d10 > requested_precision)
0703 this->precision(d10);
0704 }
0705 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
0706 return *this;
0707 }
0708 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<0>(mpfr_get_prec(val))
0709 {
0710 mpc_set_fr(this->m_data, val, GMP_RNDN);
0711 }
0712 mpc_complex_backend& operator=(mpfr_srcptr val)
0713 {
0714 if (mpc_get_prec(data()) != mpfr_get_prec(val))
0715 {
0716 mpc_complex_backend t(val);
0717 t.swap(*this);
0718 }
0719 else
0720 mpc_set_fr(this->m_data, val, GMP_RNDN);
0721 return *this;
0722 }
0723 mpc_complex_backend(const std::complex<float>& val)
0724 : detail::mpc_complex_imp<0>()
0725 {
0726 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
0727 }
0728 mpc_complex_backend(const std::complex<double>& val)
0729 : detail::mpc_complex_imp<0>()
0730 {
0731 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
0732 }
0733 mpc_complex_backend(const std::complex<long double>& val)
0734 : detail::mpc_complex_imp<0>()
0735 {
0736 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
0737 }
0738
0739 template <class T, class U>
0740 mpc_complex_backend(const T& a, const U& b, unsigned digits10)
0741 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
0742 {
0743
0744
0745 boost::multiprecision::detail::scoped_precision_options<mpfr_float> scoped(*this);
0746 (void)scoped;
0747 mpfr_float ca(a), cb(b);
0748 mpc_set_fr_fr(this->data(), ca.backend().data(), cb.backend().data(), GMP_RNDN);
0749 }
0750 template <unsigned N>
0751 mpc_complex_backend(const mpfr_float_backend<N>& a, const mpfr_float_backend<N>& b, unsigned digits10)
0752 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
0753 {
0754 mpc_set_fr_fr(this->data(), a.data(), b.data(), GMP_RNDN);
0755 }
0756
0757 mpc_complex_backend& operator=(const mpc_complex_backend& o) = default;
0758
0759 mpc_complex_backend& operator=(mpc_complex_backend&& o) noexcept = default;
0760
0761 template <class V>
0762 mpc_complex_backend& operator=(const V& v)
0763 {
0764 constexpr unsigned d10 = std::is_floating_point<V>::value ?
0765 std::numeric_limits<V>::digits10 :
0766 std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 :
0767 1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits);
0768
0769 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
0770 {
0771 BOOST_IF_CONSTEXPR(std::is_floating_point<V>::value)
0772 {
0773 if (std::numeric_limits<V>::digits > mpc_get_prec(this->data()))
0774 mpc_set_prec(this->data(), std::numeric_limits<V>::digits);
0775 }
0776 else
0777 {
0778 if (precision() < d10)
0779 this->precision(d10);
0780 }
0781 }
0782
0783 *static_cast<detail::mpc_complex_imp<0>*>(this) = v;
0784 return *this;
0785 }
0786 mpc_complex_backend& operator=(const mpc_t val)
0787 {
0788 mpc_set_prec(this->m_data, mpc_get_prec(val));
0789 mpc_set(this->m_data, val, GMP_RNDN);
0790 return *this;
0791 }
0792 template <unsigned D>
0793 mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
0794 {
0795 mpc_set_prec(this->m_data, mpc_get_prec(val.data()));
0796 mpc_set(this->m_data, val.data(), GMP_RNDN);
0797 return *this;
0798 }
0799 template <unsigned D>
0800 mpc_complex_backend& operator=(const mpfr_float_backend<D>& val)
0801 {
0802 if (D == 0 ? this->preserve_component_precision() : this->preserve_related_precision())
0803 mpc_set_prec(this->m_data, mpfr_get_prec(val.data()));
0804 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
0805 return *this;
0806 }
0807 mpc_complex_backend& operator=(const std::complex<float>& val)
0808 {
0809 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
0810 return *this;
0811 }
0812 mpc_complex_backend& operator=(const std::complex<double>& val)
0813 {
0814 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
0815 return *this;
0816 }
0817 mpc_complex_backend& operator=(const std::complex<long double>& val)
0818 {
0819 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
0820 return *this;
0821 }
0822 static unsigned default_precision() noexcept
0823 {
0824 return get_global_default_precision();
0825 }
0826 static void default_precision(unsigned v) noexcept
0827 {
0828 get_global_default_precision() = v;
0829 }
0830 static unsigned thread_default_precision() noexcept
0831 {
0832 return get_default_precision();
0833 }
0834 static void thread_default_precision(unsigned v) noexcept
0835 {
0836 get_default_precision() = v;
0837 }
0838 unsigned precision() const noexcept
0839 {
0840 return multiprecision::detail::digits2_2_10(mpc_get_prec(this->m_data));
0841 }
0842 void precision(unsigned digits10) noexcept
0843 {
0844 mpfr_prec_round(mpc_realref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
0845 mpfr_prec_round(mpc_imagref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
0846 }
0847
0848
0849
0850 static variable_precision_options default_variable_precision_options() noexcept
0851 {
0852 return get_global_default_options();
0853 }
0854 static variable_precision_options thread_default_variable_precision_options() noexcept
0855 {
0856 return get_default_options();
0857 }
0858 static void default_variable_precision_options(variable_precision_options opts)
0859 {
0860 get_global_default_options() = opts;
0861 }
0862 static void thread_default_variable_precision_options(variable_precision_options opts)
0863 {
0864 get_default_options() = opts;
0865 }
0866 };
0867
0868 template <unsigned digits10, class T>
0869 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_eq(const mpc_complex_backend<digits10>& a, const T& b) noexcept
0870 {
0871 return a.compare(b) == 0;
0872 }
0873 template <unsigned digits10, class T>
0874 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_lt(const mpc_complex_backend<digits10>& a, const T& b) noexcept
0875 {
0876 return a.compare(b) < 0;
0877 }
0878 template <unsigned digits10, class T>
0879 inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_gt(const mpc_complex_backend<digits10>& a, const T& b) noexcept
0880 {
0881 return a.compare(b) > 0;
0882 }
0883
0884 template <unsigned D1, unsigned D2>
0885 inline void eval_add(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
0886 {
0887 mpc_add(result.data(), result.data(), o.data(), GMP_RNDN);
0888 }
0889 template <unsigned D1, unsigned D2>
0890 inline void eval_add(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
0891 {
0892 mpc_add_fr(result.data(), result.data(), o.data(), GMP_RNDN);
0893 }
0894 template <unsigned D1, unsigned D2>
0895 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
0896 {
0897 mpc_sub(result.data(), result.data(), o.data(), GMP_RNDN);
0898 }
0899 template <unsigned D1, unsigned D2>
0900 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
0901 {
0902 mpc_sub_fr(result.data(), result.data(), o.data(), GMP_RNDN);
0903 }
0904 template <unsigned D1, unsigned D2>
0905 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
0906 {
0907 if ((void*)&result == (void*)&o)
0908 mpc_sqr(result.data(), o.data(), GMP_RNDN);
0909 else
0910 mpc_mul(result.data(), result.data(), o.data(), GMP_RNDN);
0911 }
0912 template <unsigned D1, unsigned D2>
0913 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
0914 {
0915 mpc_mul_fr(result.data(), result.data(), o.data(), GMP_RNDN);
0916 }
0917 template <unsigned D1, unsigned D2>
0918 inline void eval_divide(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
0919 {
0920 mpc_div(result.data(), result.data(), o.data(), GMP_RNDN);
0921 }
0922 template <unsigned D1, unsigned D2>
0923 inline void eval_divide(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
0924 {
0925 mpc_div_fr(result.data(), result.data(), o.data(), GMP_RNDN);
0926 }
0927 template <unsigned digits10>
0928 inline void eval_add(mpc_complex_backend<digits10>& result, unsigned long i)
0929 {
0930 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
0931 }
0932 template <unsigned digits10>
0933 inline void eval_subtract(mpc_complex_backend<digits10>& result, unsigned long i)
0934 {
0935 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
0936 }
0937 template <unsigned digits10>
0938 inline void eval_multiply(mpc_complex_backend<digits10>& result, unsigned long i)
0939 {
0940 mpc_mul_ui(result.data(), result.data(), i, GMP_RNDN);
0941 }
0942 template <unsigned digits10>
0943 inline void eval_divide(mpc_complex_backend<digits10>& result, unsigned long i)
0944 {
0945 mpc_div_ui(result.data(), result.data(), i, GMP_RNDN);
0946 }
0947 template <unsigned digits10>
0948 inline void eval_add(mpc_complex_backend<digits10>& result, long i)
0949 {
0950 if (i > 0)
0951 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
0952 else
0953 mpc_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
0954 }
0955 template <unsigned digits10>
0956 inline void eval_subtract(mpc_complex_backend<digits10>& result, long i)
0957 {
0958 if (i > 0)
0959 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
0960 else
0961 mpc_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
0962 }
0963 template <unsigned digits10>
0964 inline void eval_multiply(mpc_complex_backend<digits10>& result, long i)
0965 {
0966 mpc_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
0967 if (i < 0)
0968 mpc_neg(result.data(), result.data(), GMP_RNDN);
0969 }
0970 template <unsigned digits10>
0971 inline void eval_divide(mpc_complex_backend<digits10>& result, long i)
0972 {
0973 mpc_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
0974 if (i < 0)
0975 mpc_neg(result.data(), result.data(), GMP_RNDN);
0976 }
0977
0978
0979
0980 template <unsigned D1, unsigned D2, unsigned D3>
0981 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
0982 {
0983 mpc_add(a.data(), x.data(), y.data(), GMP_RNDN);
0984 }
0985 template <unsigned D1, unsigned D2, unsigned D3>
0986 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
0987 {
0988 mpc_add_fr(a.data(), x.data(), y.data(), GMP_RNDN);
0989 }
0990 template <unsigned D1, unsigned D2, unsigned D3>
0991 inline void eval_add(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
0992 {
0993 mpc_add_fr(a.data(), y.data(), x.data(), GMP_RNDN);
0994 }
0995 template <unsigned D1, unsigned D2>
0996 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
0997 {
0998 mpc_add_ui(a.data(), x.data(), y, GMP_RNDN);
0999 }
1000 template <unsigned D1, unsigned D2>
1001 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
1002 {
1003 if (y < 0)
1004 mpc_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1005 else
1006 mpc_add_ui(a.data(), x.data(), y, GMP_RNDN);
1007 }
1008 template <unsigned D1, unsigned D2>
1009 inline void eval_add(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
1010 {
1011 mpc_add_ui(a.data(), y.data(), x, GMP_RNDN);
1012 }
1013 template <unsigned D1, unsigned D2>
1014 inline void eval_add(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
1015 {
1016 if (x < 0)
1017 {
1018 mpc_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1019 mpc_neg(a.data(), a.data(), GMP_RNDN);
1020 }
1021 else
1022 mpc_add_ui(a.data(), y.data(), x, GMP_RNDN);
1023 }
1024 template <unsigned D1, unsigned D2, unsigned D3>
1025 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
1026 {
1027 mpc_sub(a.data(), x.data(), y.data(), GMP_RNDN);
1028 }
1029 template <unsigned D1, unsigned D2, unsigned D3>
1030 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
1031 {
1032 mpc_sub_fr(a.data(), x.data(), y.data(), GMP_RNDN);
1033 }
1034 template <unsigned D1, unsigned D2, unsigned D3>
1035 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
1036 {
1037 mpc_fr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
1038 }
1039 template <unsigned D1, unsigned D2>
1040 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
1041 {
1042 mpc_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1043 }
1044 template <unsigned D1, unsigned D2>
1045 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
1046 {
1047 if (y < 0)
1048 mpc_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1049 else
1050 mpc_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1051 }
1052 template <unsigned D1, unsigned D2>
1053 inline void eval_subtract(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
1054 {
1055 mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1056 }
1057 template <unsigned D1, unsigned D2>
1058 inline void eval_subtract(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
1059 {
1060 if (x < 0)
1061 {
1062 mpc_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1063 mpc_neg(a.data(), a.data(), GMP_RNDN);
1064 }
1065 else
1066 mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1067 }
1068
1069 template <unsigned D1, unsigned D2, unsigned D3>
1070 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
1071 {
1072 if ((void*)&x == (void*)&y)
1073 mpc_sqr(a.data(), x.data(), GMP_RNDN);
1074 else
1075 mpc_mul(a.data(), x.data(), y.data(), GMP_RNDN);
1076 }
1077 template <unsigned D1, unsigned D2, unsigned D3>
1078 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
1079 {
1080 mpc_mul_fr(a.data(), x.data(), y.data(), GMP_RNDN);
1081 }
1082 template <unsigned D1, unsigned D2, unsigned D3>
1083 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
1084 {
1085 mpc_mul_fr(a.data(), y.data(), x.data(), GMP_RNDN);
1086 }
1087 template <unsigned D1, unsigned D2>
1088 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
1089 {
1090 mpc_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1091 }
1092 template <unsigned D1, unsigned D2>
1093 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
1094 {
1095 if (y < 0)
1096 {
1097 mpc_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1098 a.negate();
1099 }
1100 else
1101 mpc_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1102 }
1103 template <unsigned D1, unsigned D2>
1104 inline void eval_multiply(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
1105 {
1106 mpc_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1107 }
1108 template <unsigned D1, unsigned D2>
1109 inline void eval_multiply(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
1110 {
1111 if (x < 0)
1112 {
1113 mpc_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1114 mpc_neg(a.data(), a.data(), GMP_RNDN);
1115 }
1116 else
1117 mpc_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1118 }
1119
1120 template <unsigned D1, unsigned D2, unsigned D3>
1121 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
1122 {
1123 mpc_div(a.data(), x.data(), y.data(), GMP_RNDN);
1124 }
1125 template <unsigned D1, unsigned D2, unsigned D3>
1126 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
1127 {
1128 mpc_div_fr(a.data(), x.data(), y.data(), GMP_RNDN);
1129 }
1130 template <unsigned D1, unsigned D2, unsigned D3>
1131 inline void eval_divide(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
1132 {
1133 mpc_fr_div(a.data(), x.data(), y.data(), GMP_RNDN);
1134 }
1135 template <unsigned D1, unsigned D2>
1136 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
1137 {
1138 mpc_div_ui(a.data(), x.data(), y, GMP_RNDN);
1139 }
1140 template <unsigned D1, unsigned D2>
1141 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
1142 {
1143 if (y < 0)
1144 {
1145 mpc_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1146 a.negate();
1147 }
1148 else
1149 mpc_div_ui(a.data(), x.data(), y, GMP_RNDN);
1150 }
1151 template <unsigned D1, unsigned D2>
1152 inline void eval_divide(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
1153 {
1154 mpc_ui_div(a.data(), x, y.data(), GMP_RNDN);
1155 }
1156 template <unsigned D1, unsigned D2>
1157 inline void eval_divide(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
1158 {
1159 if (x < 0)
1160 {
1161 mpc_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1162 mpc_neg(a.data(), a.data(), GMP_RNDN);
1163 }
1164 else
1165 mpc_ui_div(a.data(), x, y.data(), GMP_RNDN);
1166 }
1167
1168 template <unsigned digits10>
1169 inline bool eval_is_zero(const mpc_complex_backend<digits10>& val) noexcept
1170 {
1171 return (0 != mpfr_zero_p(mpc_realref(val.data()))) && (0 != mpfr_zero_p(mpc_imagref(val.data())));
1172 }
1173 template <unsigned digits10>
1174 inline int eval_get_sign(const mpc_complex_backend<digits10>&)
1175 {
1176 static_assert(digits10 == UINT_MAX, "Complex numbers have no sign bit.");
1177 return 0;
1178 }
1179
1180 template <unsigned digits10>
1181 inline void eval_convert_to(unsigned long* result, const mpc_complex_backend<digits10>& val)
1182 {
1183 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1184 {
1185 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1186 }
1187 mpfr_float_backend<digits10> t;
1188 mpc_real(t.data(), val.data(), GMP_RNDN);
1189 eval_convert_to(result, t);
1190 }
1191 template <unsigned digits10>
1192 inline void eval_convert_to(long* result, const mpc_complex_backend<digits10>& val)
1193 {
1194 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1195 {
1196 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1197 }
1198 mpfr_float_backend<digits10> t;
1199 mpc_real(t.data(), val.data(), GMP_RNDN);
1200 eval_convert_to(result, t);
1201 }
1202 #ifdef _MPFR_H_HAVE_INTMAX_T
1203 template <unsigned digits10>
1204 inline void eval_convert_to(unsigned long long* result, const mpc_complex_backend<digits10>& val)
1205 {
1206 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1207 {
1208 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1209 }
1210 mpfr_float_backend<digits10> t;
1211 mpc_real(t.data(), val.data(), GMP_RNDN);
1212 eval_convert_to(result, t);
1213 }
1214 template <unsigned digits10>
1215 inline void eval_convert_to(long long* result, const mpc_complex_backend<digits10>& val)
1216 {
1217 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1218 {
1219 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1220 }
1221 mpfr_float_backend<digits10> t;
1222 mpc_real(t.data(), val.data(), GMP_RNDN);
1223 eval_convert_to(result, t);
1224 }
1225 #endif
1226 template <unsigned digits10>
1227 inline void eval_convert_to(double* result, const mpc_complex_backend<digits10>& val) noexcept
1228 {
1229 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1230 {
1231 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1232 }
1233 mpfr_float_backend<digits10> t;
1234 mpc_real(t.data(), val.data(), GMP_RNDN);
1235 eval_convert_to(result, t);
1236 }
1237 template <unsigned digits10>
1238 inline void eval_convert_to(long double* result, const mpc_complex_backend<digits10>& val) noexcept
1239 {
1240 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1241 {
1242 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1243 }
1244 mpfr_float_backend<digits10> t;
1245 mpc_real(t.data(), val.data(), GMP_RNDN);
1246 eval_convert_to(result, t);
1247 }
1248 #ifdef BOOST_HAS_INT128
1249 template <unsigned digits10>
1250 inline void eval_convert_to(uint128_type* result, const mpc_complex_backend<digits10>& val)
1251 {
1252 using default_ops::eval_convert_to;
1253 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1254 {
1255 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1256 }
1257 mpfr_float_backend<digits10> t;
1258 mpc_real(t.data(), val.data(), GMP_RNDN);
1259 eval_convert_to(result, t);
1260 }
1261 template <unsigned digits10>
1262 inline void eval_convert_to(int128_type* result, const mpc_complex_backend<digits10>& val)
1263 {
1264 using default_ops::eval_convert_to;
1265 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1266 {
1267 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1268 }
1269 mpfr_float_backend<digits10> t;
1270 mpc_real(t.data(), val.data(), GMP_RNDN);
1271 eval_convert_to(result, t);
1272 }
1273 #endif
1274 #ifdef BOOST_HAS_FLOAT128
1275 template <unsigned digits10>
1276 inline void eval_convert_to(float128_type* result, const mpc_complex_backend<digits10>& val)
1277 {
1278 using default_ops::eval_convert_to;
1279 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1280 {
1281 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1282 }
1283 mpfr_float_backend<digits10> t;
1284 mpc_real(t.data(), val.data(), GMP_RNDN);
1285 eval_convert_to(result, t);
1286 }
1287 #endif
1288
1289 template <mpfr_allocation_type AllocationType>
1290 inline void assign_components_set_precision(mpc_complex_backend<0>& result, const mpfr_float_backend<0, AllocationType>& a, const mpfr_float_backend<0, AllocationType>& b)
1291 {
1292 if (result.thread_default_variable_precision_options() >= variable_precision_options::preserve_component_precision)
1293 {
1294 unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
1295 mpc_set_prec(result.data(), prec);
1296 }
1297 }
1298 template <unsigned D2, mpfr_allocation_type AllocationType>
1299 inline void assign_components_set_precision(mpc_complex_backend<0>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
1300 {
1301 if (result.thread_default_variable_precision_options() >= variable_precision_options::preserve_related_precision)
1302 {
1303 unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
1304 mpc_set_prec(result.data(), prec);
1305 }
1306 }
1307 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1308 inline void assign_components_set_precision(mpc_complex_backend<D1>&, const mpfr_float_backend<D2, AllocationType>&, const mpfr_float_backend<D2, AllocationType>&)
1309 {
1310 }
1311
1312 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1313 inline void assign_components(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
1314 {
1315
1316
1317
1318
1319 assign_components_set_precision(result, a, b);
1320 using default_ops::eval_fpclassify;
1321 if (eval_fpclassify(a) == static_cast<int>(FP_NAN))
1322 {
1323 mpc_set_fr(result.data(), a.data(), GMP_RNDN);
1324 }
1325 else if (eval_fpclassify(b) == static_cast<int>(FP_NAN))
1326 {
1327 mpc_set_fr(result.data(), b.data(), GMP_RNDN);
1328 }
1329 else
1330 {
1331 mpc_set_fr_fr(result.data(), a.data(), b.data(), GMP_RNDN);
1332 }
1333 }
1334
1335 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1336 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long a, unsigned long b)
1337 {
1338 mpc_set_ui_ui(result.data(), a, b, GMP_RNDN);
1339 }
1340
1341 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1342 inline void assign_components(mpc_complex_backend<D1>& result, long a, long b)
1343 {
1344 mpc_set_si_si(result.data(), a, b, GMP_RNDN);
1345 }
1346
1347 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1348 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1349 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long long a, unsigned long long b)
1350 {
1351 mpc_set_uj_uj(result.data(), a, b, GMP_RNDN);
1352 }
1353
1354 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1355 inline void assign_components(mpc_complex_backend<D1>& result, long long a, long long b)
1356 {
1357 mpc_set_sj_sj(result.data(), a, b, GMP_RNDN);
1358 }
1359 #endif
1360
1361 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1362 inline void assign_components(mpc_complex_backend<D1>& result, double a, double b)
1363 {
1364 if (BOOST_MP_ISNAN(a))
1365 {
1366 mpc_set_d(result.data(), a, GMP_RNDN);
1367 }
1368 else if (BOOST_MP_ISNAN(b))
1369 {
1370 mpc_set_d(result.data(), b, GMP_RNDN);
1371 }
1372 else
1373 {
1374 mpc_set_d_d(result.data(), a, b, GMP_RNDN);
1375 }
1376 }
1377
1378 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1379 inline void assign_components(mpc_complex_backend<D1>& result, long double a, long double b)
1380 {
1381 if (BOOST_MP_ISNAN(a))
1382 {
1383 mpc_set_d(result.data(), a, GMP_RNDN);
1384 }
1385 else if (BOOST_MP_ISNAN(b))
1386 {
1387 mpc_set_d(result.data(), b, GMP_RNDN);
1388 }
1389 else
1390 {
1391 mpc_set_ld_ld(result.data(), a, b, GMP_RNDN);
1392 }
1393 }
1394
1395
1396
1397
1398 template <unsigned Digits10>
1399 inline void eval_sqrt(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& val)
1400 {
1401 mpc_sqrt(result.data(), val.data(), GMP_RNDN);
1402 }
1403
1404 template <unsigned Digits10>
1405 inline void eval_pow(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& b, const mpc_complex_backend<Digits10>& e)
1406 {
1407 mpc_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1408 }
1409
1410 template <unsigned Digits10>
1411 inline void eval_exp(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1412 {
1413 mpc_exp(result.data(), arg.data(), GMP_RNDN);
1414 }
1415
1416 template <unsigned Digits10>
1417 inline void eval_log(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1418 {
1419 mpc_log(result.data(), arg.data(), GMP_RNDN);
1420 }
1421
1422 template <unsigned Digits10>
1423 inline void eval_log10(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1424 {
1425 mpc_log10(result.data(), arg.data(), GMP_RNDN);
1426 }
1427
1428 template <unsigned Digits10>
1429 inline void eval_sin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1430 {
1431 mpc_sin(result.data(), arg.data(), GMP_RNDN);
1432 }
1433
1434 template <unsigned Digits10>
1435 inline void eval_cos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1436 {
1437 mpc_cos(result.data(), arg.data(), GMP_RNDN);
1438 }
1439
1440 template <unsigned Digits10>
1441 inline void eval_tan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1442 {
1443 mpc_tan(result.data(), arg.data(), GMP_RNDN);
1444 }
1445
1446 template <unsigned Digits10>
1447 inline void eval_asin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1448 {
1449 mpc_asin(result.data(), arg.data(), GMP_RNDN);
1450 }
1451
1452 template <unsigned Digits10>
1453 inline void eval_acos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1454 {
1455 mpc_acos(result.data(), arg.data(), GMP_RNDN);
1456 }
1457
1458 template <unsigned Digits10>
1459 inline void eval_atan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1460 {
1461 mpc_atan(result.data(), arg.data(), GMP_RNDN);
1462 }
1463
1464 template <unsigned Digits10>
1465 inline void eval_sinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1466 {
1467 mpc_sinh(result.data(), arg.data(), GMP_RNDN);
1468 }
1469
1470 template <unsigned Digits10>
1471 inline void eval_cosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1472 {
1473 mpc_cosh(result.data(), arg.data(), GMP_RNDN);
1474 }
1475
1476 template <unsigned Digits10>
1477 inline void eval_tanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1478 {
1479 mpc_tanh(result.data(), arg.data(), GMP_RNDN);
1480 }
1481
1482 template <unsigned Digits10>
1483 inline void eval_asinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1484 {
1485 mpc_asinh(result.data(), arg.data(), GMP_RNDN);
1486 }
1487
1488 template <unsigned Digits10>
1489 inline void eval_acosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1490 {
1491 mpc_acosh(result.data(), arg.data(), GMP_RNDN);
1492 }
1493
1494 template <unsigned Digits10>
1495 inline void eval_atanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1496 {
1497 mpc_atanh(result.data(), arg.data(), GMP_RNDN);
1498 }
1499
1500 template <unsigned Digits10>
1501 inline void eval_conj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1502 {
1503 mpc_conj(result.data(), arg.data(), GMP_RNDN);
1504 }
1505
1506 template <unsigned Digits10>
1507 inline void eval_proj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1508 {
1509 mpc_proj(result.data(), arg.data(), GMP_RNDN);
1510 }
1511
1512 template <unsigned Digits10>
1513 inline void eval_real(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1514 {
1515 mpfr_set_prec(result.data(), mpfr_get_prec(mpc_realref(arg.data())));
1516 mpfr_set(result.data(), mpc_realref(arg.data()), GMP_RNDN);
1517 }
1518 template <unsigned Digits10>
1519 inline void eval_imag(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1520 {
1521 mpfr_set_prec(result.data(), mpfr_get_prec(mpc_imagref(arg.data())));
1522 mpfr_set(result.data(), mpc_imagref(arg.data()), GMP_RNDN);
1523 }
1524
1525 template <unsigned Digits10>
1526 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1527 {
1528 mpfr_set(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1529 }
1530
1531 template <unsigned Digits10>
1532 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1533 {
1534 mpfr_set(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1535 }
1536 template <unsigned Digits10>
1537 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1538 {
1539 mpfr_set_z(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1540 }
1541 template <unsigned Digits10>
1542 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1543 {
1544 mpfr_set_q(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1545 }
1546 template <unsigned Digits10>
1547 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1548 {
1549 mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1550 }
1551 template <unsigned Digits10>
1552 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1553 {
1554 mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1555 }
1556 template <unsigned Digits10>
1557 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const int& arg)
1558 {
1559 mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1560 }
1561 template <unsigned Digits10>
1562 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long& arg)
1563 {
1564 mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1565 }
1566 template <unsigned Digits10>
1567 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const float& arg)
1568 {
1569 mpfr_set_flt(mpc_realref(result.data()), arg, GMP_RNDN);
1570 }
1571 template <unsigned Digits10>
1572 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const double& arg)
1573 {
1574 mpfr_set_d(mpc_realref(result.data()), arg, GMP_RNDN);
1575 }
1576 template <unsigned Digits10>
1577 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long double& arg)
1578 {
1579 mpfr_set_ld(mpc_realref(result.data()), arg, GMP_RNDN);
1580 }
1581 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1582 template <unsigned Digits10>
1583 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1584 {
1585 mpfr_set_uj(mpc_realref(result.data()), arg, GMP_RNDN);
1586 }
1587 template <unsigned Digits10>
1588 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long long& arg)
1589 {
1590 mpfr_set_sj(mpc_realref(result.data()), arg, GMP_RNDN);
1591 }
1592 #endif
1593
1594 template <unsigned Digits10>
1595 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1596 {
1597 mpfr_set_z(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1598 }
1599 template <unsigned Digits10>
1600 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1601 {
1602 mpfr_set_q(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1603 }
1604 template <unsigned Digits10>
1605 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1606 {
1607 mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1608 }
1609 template <unsigned Digits10>
1610 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1611 {
1612 mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1613 }
1614 template <unsigned Digits10>
1615 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const int& arg)
1616 {
1617 mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1618 }
1619 template <unsigned Digits10>
1620 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long& arg)
1621 {
1622 mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1623 }
1624 template <unsigned Digits10>
1625 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const float& arg)
1626 {
1627 mpfr_set_flt(mpc_imagref(result.data()), arg, GMP_RNDN);
1628 }
1629 template <unsigned Digits10>
1630 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const double& arg)
1631 {
1632 mpfr_set_d(mpc_imagref(result.data()), arg, GMP_RNDN);
1633 }
1634 template <unsigned Digits10>
1635 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long double& arg)
1636 {
1637 mpfr_set_ld(mpc_imagref(result.data()), arg, GMP_RNDN);
1638 }
1639 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1640 template <unsigned Digits10>
1641 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1642 {
1643 mpfr_set_uj(mpc_imagref(result.data()), arg, GMP_RNDN);
1644 }
1645 template <unsigned Digits10>
1646 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long long& arg)
1647 {
1648 mpfr_set_sj(mpc_imagref(result.data()), arg, GMP_RNDN);
1649 }
1650 #endif
1651
1652 template <unsigned Digits10>
1653 inline std::size_t hash_value(const mpc_complex_backend<Digits10>& val)
1654 {
1655 std::size_t result = 0;
1656 std::size_t len = val.data()[0].re[0]._mpfr_prec / mp_bits_per_limb;
1657 if (val.data()[0].re[0]._mpfr_prec % mp_bits_per_limb)
1658 ++len;
1659 for (std::size_t i = 0; i < len; ++i)
1660 boost::multiprecision::detail::hash_combine(result, val.data()[0].re[0]._mpfr_d[i]);
1661 boost::multiprecision::detail::hash_combine(result, val.data()[0].re[0]._mpfr_exp, val.data()[0].re[0]._mpfr_sign);
1662
1663 len = val.data()[0].im[0]._mpfr_prec / mp_bits_per_limb;
1664 if (val.data()[0].im[0]._mpfr_prec % mp_bits_per_limb)
1665 ++len;
1666 for (std::size_t i = 0; i < len; ++i)
1667 boost::multiprecision::detail::hash_combine(result, val.data()[0].im[0]._mpfr_d[i]);
1668 boost::multiprecision::detail::hash_combine(result, val.data()[0].im[0]._mpfr_exp, val.data()[0].im[0]._mpfr_sign);
1669 return result;
1670 }
1671
1672 }
1673
1674 namespace detail {
1675 template <>
1676 struct is_variable_precision<backends::mpc_complex_backend<0> > : public std::integral_constant<bool, true>
1677 {};
1678 }
1679
1680 template <>
1681 struct number_category<detail::canonical<mpc_t, backends::mpc_complex_backend<0> >::type> : public std::integral_constant<int, number_kind_floating_point>
1682 {};
1683
1684 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1685 struct component_type<number<mpc_complex_backend<Digits10>, ExpressionTemplates> >
1686 {
1687 using type = number<mpfr_float_backend<Digits10>, ExpressionTemplates>;
1688 };
1689
1690 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1691 struct component_type<number<backends::logged_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> >
1692 {
1693 using type = number<mpfr_float_backend<Digits10>, ExpressionTemplates>;
1694 };
1695 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1696 struct component_type<number<backends::debug_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> >
1697 {
1698 using type = number<backends::debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates>;
1699 };
1700
1701 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1702 struct complex_result_from_scalar<number<mpfr_float_backend<Digits10>, ExpressionTemplates> >
1703 {
1704 using type = number<mpc_complex_backend<Digits10>, ExpressionTemplates>;
1705 };
1706 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1707 struct complex_result_from_scalar<number<backends::logged_adaptor<mpfr_float_backend<Digits10>>, ExpressionTemplates> >
1708 {
1709 using type = number<mpc_complex_backend<Digits10>, ExpressionTemplates>;
1710 };
1711 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1712 struct complex_result_from_scalar<number<backends::debug_adaptor<mpfr_float_backend<Digits10>>, ExpressionTemplates> >
1713 {
1714 using type = number<backends::debug_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates>;
1715 };
1716
1717 }
1718
1719 }
1720
1721 #endif