1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright 2018 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_MULTIPRECISION_MPC_HPP
7 #define BOOST_MULTIPRECISION_MPC_HPP
8
9 #include <boost/multiprecision/number.hpp>
10 #include <boost/cstdint.hpp>
11 #include <boost/multiprecision/detail/digits.hpp>
12 #include <boost/multiprecision/traits/is_variable_precision.hpp>
13 #include <boost/multiprecision/mpfr.hpp>
14 #include <boost/multiprecision/logged_adaptor.hpp>
15 #include <boost/functional/hash_fwd.hpp>
16 #include <mpc.h>
17 #include <cmath>
18 #include <algorithm>
19 #include <complex>
20
21 #ifndef BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION
22 # define BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION 20
23 #endif
24
25 namespace boost{
26 namespace multiprecision{
27 namespace backends{
28
29 template <unsigned digits10>
30 struct mpc_complex_backend;
31
32 } // namespace backends
33
34 template <unsigned digits10>
35 struct number_category<backends::mpc_complex_backend<digits10> > : public mpl::int_<number_kind_complex>{};
36
37 namespace backends{
38
39 namespace detail{
40
41
mpc_copy_precision(mpc_t dest,const mpc_t src)42 inline void mpc_copy_precision(mpc_t dest, const mpc_t src)
43 {
44 mpfr_prec_t p_dest = mpc_get_prec(dest);
45 mpfr_prec_t p_src = mpc_get_prec(src);
46 if (p_dest != p_src)
47 mpc_set_prec(dest, p_src);
48 }
mpc_copy_precision(mpc_t dest,const mpc_t src1,const mpc_t src2)49 inline void mpc_copy_precision(mpc_t dest, const mpc_t src1, const mpc_t src2)
50 {
51 mpfr_prec_t p_dest = mpc_get_prec(dest);
52 mpfr_prec_t p_src1 = mpc_get_prec(src1);
53 mpfr_prec_t p_src2 = mpc_get_prec(src2);
54 if (p_src2 > p_src1)
55 p_src1 = p_src2;
56 if (p_dest != p_src1)
57 mpc_set_prec(dest, p_src1);
58 }
59
60
61 template <unsigned digits10>
62 struct mpc_complex_imp
63 {
64 #ifdef BOOST_HAS_LONG_LONG
65 typedef mpl::list<long, boost::long_long_type> signed_types;
66 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
67 #else
68 typedef mpl::list<long> signed_types;
69 typedef mpl::list<unsigned long> unsigned_types;
70 #endif
71 typedef mpl::list<double, long double> float_types;
72 typedef long exponent_type;
73
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp74 mpc_complex_imp()
75 {
76 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
77 mpc_set_ui(m_data, 0u, GMP_RNDN);
78 }
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp79 mpc_complex_imp(unsigned digits2)
80 {
81 mpc_init2(m_data, digits2);
82 mpc_set_ui(m_data, 0u, GMP_RNDN);
83 }
84
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp85 mpc_complex_imp(const mpc_complex_imp& o)
86 {
87 mpc_init2(m_data, mpc_get_prec(o.m_data));
88 if(o.m_data[0].re[0]._mpfr_d)
89 mpc_set(m_data, o.m_data, GMP_RNDN);
90 }
91 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp92 mpc_complex_imp(mpc_complex_imp&& o) BOOST_NOEXCEPT
93 {
94 m_data[0] = o.m_data[0];
95 o.m_data[0].re[0]._mpfr_d = 0;
96 }
97 #endif
operator =boost::multiprecision::backends::detail::mpc_complex_imp98 mpc_complex_imp& operator = (const mpc_complex_imp& o)
99 {
100 if( (o.m_data[0].re[0]._mpfr_d) && (this != &o) )
101 {
102 if (m_data[0].re[0]._mpfr_d == 0)
103 mpc_init2(m_data, mpc_get_prec(o.m_data));
104 mpc_set(m_data, o.m_data, GMP_RNDD);
105 }
106 return *this;
107 }
108 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::detail::mpc_complex_imp109 mpc_complex_imp& operator = (mpc_complex_imp&& o) BOOST_NOEXCEPT
110 {
111 mpc_swap(m_data, o.m_data);
112 return *this;
113 }
114 #endif
115 #ifdef BOOST_HAS_LONG_LONG
116 #ifdef _MPFR_H_HAVE_INTMAX_T
operator =boost::multiprecision::backends::detail::mpc_complex_imp117 mpc_complex_imp& operator = (boost::ulong_long_type i)
118 {
119 if(m_data[0].re[0]._mpfr_d == 0)
120 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
121 mpc_set_uj(data(), i, GMP_RNDD);
122 return *this;
123 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp124 mpc_complex_imp& operator = (boost::long_long_type i)
125 {
126 if(m_data[0].re[0]._mpfr_d == 0)
127 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
128 mpc_set_sj(data(), i, GMP_RNDD);
129 return *this;
130 }
131 #else
operator =boost::multiprecision::backends::detail::mpc_complex_imp132 mpc_complex_imp& operator = (boost::ulong_long_type i)
133 {
134 mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data));
135 f = i;
136 mpc_set_fr(this->data(), f.data(), GMP_RNDN);
137 return *this;
138 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp139 mpc_complex_imp& operator = (boost::long_long_type i)
140 {
141 mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data));
142 f = i;
143 mpc_set_fr(this->data(), f.data(), GMP_RNDN);
144 return *this;
145 }
146 #endif
147 #endif
operator =boost::multiprecision::backends::detail::mpc_complex_imp148 mpc_complex_imp& operator = (unsigned long i)
149 {
150 if(m_data[0].re[0]._mpfr_d == 0)
151 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
152 mpc_set_ui(m_data, i, GMP_RNDN);
153 return *this;
154 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp155 mpc_complex_imp& operator = (long i)
156 {
157 if(m_data[0].re[0]._mpfr_d == 0)
158 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
159 mpc_set_si(m_data, i, GMP_RNDN);
160 return *this;
161 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp162 mpc_complex_imp& operator = (double d)
163 {
164 if(m_data[0].re[0]._mpfr_d == 0)
165 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
166 mpc_set_d(m_data, d, GMP_RNDN);
167 return *this;
168 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp169 mpc_complex_imp& operator = (long double d)
170 {
171 if (m_data[0].re[0]._mpfr_d == 0)
172 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
173 mpc_set_ld(m_data, d, GMP_RNDN);
174 return *this;
175 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp176 mpc_complex_imp& operator = (mpz_t i)
177 {
178 if (m_data[0].re[0]._mpfr_d == 0)
179 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
180 mpc_set_z(m_data, i, GMP_RNDN);
181 return *this;
182 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp183 mpc_complex_imp& operator = (gmp_int i)
184 {
185 if (m_data[0].re[0]._mpfr_d == 0)
186 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
187 mpc_set_z(m_data, i.data(), GMP_RNDN);
188 return *this;
189 }
190
operator =boost::multiprecision::backends::detail::mpc_complex_imp191 mpc_complex_imp& operator = (const char* s)
192 {
193 using default_ops::eval_fpclassify;
194
195 if(m_data[0].re[0]._mpfr_d == 0)
196 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
197
198 mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data));
199
200 if(s && (*s == '('))
201 {
202 std::string part;
203 const char* p = ++s;
204 while(*p && (*p != ',') && (*p != ')'))
205 ++p;
206 part.assign(s, p);
207 if(part.size())
208 a = part.c_str();
209 else
210 a = 0uL;
211 s = p;
212 if(*p && (*p != ')'))
213 {
214 ++p;
215 while(*p && (*p != ')'))
216 ++p;
217 part.assign(s + 1, p);
218 }
219 else
220 part.erase();
221 if(part.size())
222 b = part.c_str();
223 else
224 b = 0uL;
225 }
226 else
227 {
228 a = s;
229 b = 0uL;
230 }
231
232 if(eval_fpclassify(a) == (int)FP_NAN)
233 {
234 mpc_set_fr(this->data(), a.data(), GMP_RNDN);
235 }
236 else if(eval_fpclassify(b) == (int)FP_NAN)
237 {
238 mpc_set_fr(this->data(), b.data(), GMP_RNDN);
239 }
240 else
241 {
242 mpc_set_fr_fr(m_data, a.data(), b.data(), GMP_RNDN);
243 }
244 return *this;
245 }
swapboost::multiprecision::backends::detail::mpc_complex_imp246 void swap(mpc_complex_imp& o) BOOST_NOEXCEPT
247 {
248 mpc_swap(m_data, o.m_data);
249 }
strboost::multiprecision::backends::detail::mpc_complex_imp250 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
251 {
252 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
253
254 mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data));
255
256 mpc_real(a.data(), m_data, GMP_RNDD);
257 mpc_imag(b.data(), m_data, GMP_RNDD);
258
259 if(eval_is_zero(b))
260 return a.str(digits, f);
261
262 return "(" + a.str(digits, f) + "," + b.str(digits, f) + ")";
263 }
~mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp264 ~mpc_complex_imp() BOOST_NOEXCEPT
265 {
266 if(m_data[0].re[0]._mpfr_d)
267 mpc_clear(m_data);
268 }
negateboost::multiprecision::backends::detail::mpc_complex_imp269 void negate() BOOST_NOEXCEPT
270 {
271 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
272 mpc_neg(m_data, m_data, GMP_RNDD);
273 }
compareboost::multiprecision::backends::detail::mpc_complex_imp274 int compare(const mpc_complex_imp& o)const BOOST_NOEXCEPT
275 {
276 BOOST_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d);
277 return mpc_cmp(m_data, o.m_data);
278 }
compareboost::multiprecision::backends::detail::mpc_complex_imp279 int compare(const mpc_complex_backend<digits10>& o)const BOOST_NOEXCEPT
280 {
281 BOOST_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d);
282 return mpc_cmp(m_data, o.data());
283 }
compareboost::multiprecision::backends::detail::mpc_complex_imp284 int compare(long int i)const BOOST_NOEXCEPT
285 {
286 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
287 return mpc_cmp_si(m_data, i);
288 }
compareboost::multiprecision::backends::detail::mpc_complex_imp289 int compare(unsigned long int i)const BOOST_NOEXCEPT
290 {
291 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
292 static const unsigned long int max_val = (std::numeric_limits<long>::max)();
293 if (i > max_val)
294 {
295 mpc_complex_imp d(mpc_get_prec(m_data));
296 d = i;
297 return compare(d);
298 }
299 return mpc_cmp_si(m_data, (long)i);
300 }
301 template <class V>
compareboost::multiprecision::backends::detail::mpc_complex_imp302 int compare(const V& v)const BOOST_NOEXCEPT
303 {
304 mpc_complex_imp d(mpc_get_prec(m_data));
305 d = v;
306 return compare(d);
307 }
databoost::multiprecision::backends::detail::mpc_complex_imp308 mpc_t& data() BOOST_NOEXCEPT
309 {
310 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
311 return m_data;
312 }
databoost::multiprecision::backends::detail::mpc_complex_imp313 const mpc_t& data()const BOOST_NOEXCEPT
314 {
315 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
316 return m_data;
317 }
318 protected:
319 mpc_t m_data;
get_default_precisionboost::multiprecision::backends::detail::mpc_complex_imp320 static unsigned& get_default_precision() BOOST_NOEXCEPT
321 {
322 static unsigned val = BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION;
323 return val;
324 }
325 };
326
327 } // namespace detail
328
329 template <unsigned digits10>
330 struct mpc_complex_backend : public detail::mpc_complex_imp<digits10>
331 {
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend332 mpc_complex_backend() : detail::mpc_complex_imp<digits10>() {}
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend333 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<digits10>(o) {}
334 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend335 mpc_complex_backend(mpc_complex_backend&& o) : detail::mpc_complex_imp<digits10>(static_cast<detail::mpc_complex_imp<digits10>&&>(o)) {}
336 #endif
337 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend338 mpc_complex_backend(const mpc_complex_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
339 : detail::mpc_complex_imp<digits10>()
340 {
341 mpc_set(this->m_data, val.data(), GMP_RNDN);
342 }
343 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend344 explicit mpc_complex_backend(const mpc_complex_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
345 : detail::mpc_complex_imp<digits10>()
346 {
347 mpc_set(this->m_data, val.data(), GMP_RNDN);
348 }
349 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend350 mpc_complex_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
351 : detail::mpc_complex_imp<digits10>()
352 {
353 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
354 }
355 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend356 explicit mpc_complex_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
357 : detail::mpc_complex_imp<digits10>()
358 {
359 mpc_set(this->m_data, val.data(), GMP_RNDN);
360 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend361 mpc_complex_backend(const mpc_t val)
362 : detail::mpc_complex_imp<digits10>()
363 {
364 mpc_set(this->m_data, val, GMP_RNDN);
365 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend366 mpc_complex_backend(const std::complex<float>& val)
367 : detail::mpc_complex_imp<digits10>()
368 {
369 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
370 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend371 mpc_complex_backend(const std::complex<double>& val)
372 : detail::mpc_complex_imp<digits10>()
373 {
374 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
375 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend376 mpc_complex_backend(const std::complex<long double>& val)
377 : detail::mpc_complex_imp<digits10>()
378 {
379 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
380 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend381 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<digits10>()
382 {
383 mpc_set_z(this->m_data, val, GMP_RNDN);
384 }
operator =boost::multiprecision::backends::mpc_complex_backend385 mpc_complex_backend& operator=(mpz_srcptr val)
386 {
387 mpc_set_z(this->m_data, val, GMP_RNDN);
388 return *this;
389 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend390 mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<digits10>()
391 {
392 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
393 }
operator =boost::multiprecision::backends::mpc_complex_backend394 mpc_complex_backend& operator=(gmp_int const& val)
395 {
396 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
397 return *this;
398 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend399 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<digits10>()
400 {
401 mpc_set_f(this->m_data, val, GMP_RNDN);
402 }
operator =boost::multiprecision::backends::mpc_complex_backend403 mpc_complex_backend& operator=(mpf_srcptr val)
404 {
405 mpc_set_f(this->m_data, val, GMP_RNDN);
406 return *this;
407 }
408 template <unsigned D10>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend409 mpc_complex_backend(gmp_float<D10> const& val) : detail::mpc_complex_imp<digits10>()
410 {
411 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
412 }
413 template <unsigned D10>
operator =boost::multiprecision::backends::mpc_complex_backend414 mpc_complex_backend& operator=(gmp_float<D10> const& val)
415 {
416 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
417 return *this;
418 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend419 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<digits10>()
420 {
421 mpc_set_q(this->m_data, val, GMP_RNDN);
422 }
operator =boost::multiprecision::backends::mpc_complex_backend423 mpc_complex_backend& operator=(mpq_srcptr val)
424 {
425 mpc_set_q(this->m_data, val, GMP_RNDN);
426 return *this;
427 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend428 mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<digits10>()
429 {
430 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
431 }
operator =boost::multiprecision::backends::mpc_complex_backend432 mpc_complex_backend& operator=(gmp_rational const& val)
433 {
434 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
435 return *this;
436 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend437 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<digits10>()
438 {
439 mpc_set_fr(this->m_data, val, GMP_RNDN);
440 }
operator =boost::multiprecision::backends::mpc_complex_backend441 mpc_complex_backend& operator=(mpfr_srcptr val)
442 {
443 mpc_set_fr(this->m_data, val, GMP_RNDN);
444 return *this;
445 }
446 template <unsigned D10, mpfr_allocation_type AllocationType>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend447 mpc_complex_backend(mpfr_float_backend<D10, AllocationType> const& val) : detail::mpc_complex_imp<digits10>()
448 {
449 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
450 }
451 template <unsigned D10, mpfr_allocation_type AllocationType>
operator =boost::multiprecision::backends::mpc_complex_backend452 mpc_complex_backend& operator=(mpfr_float_backend<D10, AllocationType> const& val)
453 {
454 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
455 return *this;
456 }
operator =boost::multiprecision::backends::mpc_complex_backend457 mpc_complex_backend& operator=(const mpc_complex_backend& o)
458 {
459 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10> const&>(o);
460 return *this;
461 }
462 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::mpc_complex_backend463 mpc_complex_backend& operator=(mpc_complex_backend&& o) BOOST_NOEXCEPT
464 {
465 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10>&&>(o);
466 return *this;
467 }
468 #endif
469 template <class V>
operator =boost::multiprecision::backends::mpc_complex_backend470 mpc_complex_backend& operator=(const V& v)
471 {
472 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = v;
473 return *this;
474 }
operator =boost::multiprecision::backends::mpc_complex_backend475 mpc_complex_backend& operator=(const mpc_t val)
476 {
477 mpc_set(this->m_data, val, GMP_RNDN);
478 return *this;
479 }
operator =boost::multiprecision::backends::mpc_complex_backend480 mpc_complex_backend& operator=(const std::complex<float>& val)
481 {
482 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
483 return *this;
484 }
operator =boost::multiprecision::backends::mpc_complex_backend485 mpc_complex_backend& operator=(const std::complex<double>& val)
486 {
487 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
488 return *this;
489 }
operator =boost::multiprecision::backends::mpc_complex_backend490 mpc_complex_backend& operator=(const std::complex<long double>& val)
491 {
492 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
493 return *this;
494 }
495 // We don't change our precision here, this is a fixed precision type:
496 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend497 mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
498 {
499 mpc_set(this->m_data, val.data(), GMP_RNDN);
500 return *this;
501 }
502 };
503
504 template <>
505 struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0>
506 {
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend507 mpc_complex_backend() : detail::mpc_complex_imp<0>() {}
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend508 mpc_complex_backend(const mpc_t val)
509 : detail::mpc_complex_imp<0>(mpc_get_prec(val))
510 {
511 mpc_set(this->m_data, val, GMP_RNDN);
512 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend513 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<0>(o) {}
514 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend515 mpc_complex_backend(mpc_complex_backend&& o) BOOST_NOEXCEPT : detail::mpc_complex_imp<0>(static_cast<detail::mpc_complex_imp<0>&&>(o)) {}
516 #endif
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend517 mpc_complex_backend(const mpc_complex_backend& o, unsigned digits10)
518 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
519 {
520 mpc_set(this->m_data, o.data(), GMP_RNDN);
521 }
522 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend523 mpc_complex_backend(const mpc_complex_backend<D>& val)
524 : detail::mpc_complex_imp<0>(mpc_get_prec(val.data()))
525 {
526 mpc_set(this->m_data, val.data(), GMP_RNDN);
527 }
528 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend529 mpc_complex_backend(const mpfr_float_backend<D>& val)
530 : detail::mpc_complex_imp<0>(mpfr_get_prec(val.data()))
531 {
532 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
533 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend534 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<0>()
535 {
536 mpc_set_z(this->m_data, val, GMP_RNDN);
537 }
operator =boost::multiprecision::backends::mpc_complex_backend538 mpc_complex_backend& operator=(mpz_srcptr val)
539 {
540 mpc_set_z(this->m_data, val, GMP_RNDN);
541 return *this;
542 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend543 mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<0>()
544 {
545 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
546 }
operator =boost::multiprecision::backends::mpc_complex_backend547 mpc_complex_backend& operator=(gmp_int const& val)
548 {
549 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
550 return *this;
551 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend552 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val))
553 {
554 mpc_set_f(this->m_data, val, GMP_RNDN);
555 }
operator =boost::multiprecision::backends::mpc_complex_backend556 mpc_complex_backend& operator=(mpf_srcptr val)
557 {
558 if (mpc_get_prec(data()) != mpf_get_prec(val))
559 {
560 mpc_complex_backend t(val);
561 t.swap(*this);
562 }
563 else
564 mpc_set_f(this->m_data, val, GMP_RNDN);
565 return *this;
566 }
567 template <unsigned digits10>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend568 mpc_complex_backend(gmp_float<digits10> const& val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val.data()))
569 {
570 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
571 }
572 template <unsigned digits10>
operator =boost::multiprecision::backends::mpc_complex_backend573 mpc_complex_backend& operator=(gmp_float<digits10> const& val)
574 {
575 if (mpc_get_prec(data()) != mpf_get_prec(val.data()))
576 {
577 mpc_complex_backend t(val);
578 t.swap(*this);
579 }
580 else
581 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
582 return *this;
583 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend584 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<0>()
585 {
586 mpc_set_q(this->m_data, val, GMP_RNDN);
587 }
operator =boost::multiprecision::backends::mpc_complex_backend588 mpc_complex_backend& operator=(mpq_srcptr val)
589 {
590 mpc_set_q(this->m_data, val, GMP_RNDN);
591 return *this;
592 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend593 mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<0>()
594 {
595 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
596 }
operator =boost::multiprecision::backends::mpc_complex_backend597 mpc_complex_backend& operator=(gmp_rational const& val)
598 {
599 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
600 return *this;
601 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend602 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<0>(mpfr_get_prec(val))
603 {
604 mpc_set_fr(this->m_data, val, GMP_RNDN);
605 }
operator =boost::multiprecision::backends::mpc_complex_backend606 mpc_complex_backend& operator=(mpfr_srcptr val)
607 {
608 if (mpc_get_prec(data()) != mpfr_get_prec(val))
609 {
610 mpc_complex_backend t(val);
611 t.swap(*this);
612 }
613 else
614 mpc_set_fr(this->m_data, val, GMP_RNDN);
615 return *this;
616 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend617 mpc_complex_backend(const std::complex<float>& val)
618 : detail::mpc_complex_imp<0>()
619 {
620 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
621 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend622 mpc_complex_backend(const std::complex<double>& val)
623 : detail::mpc_complex_imp<0>()
624 {
625 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
626 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend627 mpc_complex_backend(const std::complex<long double>& val)
628 : detail::mpc_complex_imp<0>()
629 {
630 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
631 }
632 // Construction with precision:
633 template <class T, class U>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend634 mpc_complex_backend(const T& a, const U& b, unsigned digits10)
635 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
636 {
637 // We can't use assign_components here because it copies the precision of
638 // a and b, not digits10....
639 mpfr_float ca(a), cb(b);
640 mpc_set_fr_fr(this->data(), ca.backend().data(), cb.backend().data(), GMP_RNDN);
641 }
642 template <unsigned N>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend643 mpc_complex_backend(const mpfr_float_backend<N>& a, const mpfr_float_backend<N>& b, unsigned digits10)
644 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
645 {
646 mpc_set_fr_fr(this->data(), a.data(), b.data(), GMP_RNDN);
647 }
648
operator =boost::multiprecision::backends::mpc_complex_backend649 mpc_complex_backend& operator=(const mpc_complex_backend& o)
650 {
651 if (this != &o)
652 {
653 detail::mpc_copy_precision(this->m_data, o.data());
654 mpc_set(this->m_data, o.data(), GMP_RNDN);
655 }
656 return *this;
657 }
658 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::mpc_complex_backend659 mpc_complex_backend& operator=(mpc_complex_backend&& o) BOOST_NOEXCEPT
660 {
661 *static_cast<detail::mpc_complex_imp<0>*>(this) = static_cast<detail::mpc_complex_imp<0> &&>(o);
662 return *this;
663 }
664 #endif
665 template <class V>
operator =boost::multiprecision::backends::mpc_complex_backend666 mpc_complex_backend& operator=(const V& v)
667 {
668 *static_cast<detail::mpc_complex_imp<0>*>(this) = v;
669 return *this;
670 }
operator =boost::multiprecision::backends::mpc_complex_backend671 mpc_complex_backend& operator=(const mpc_t val)
672 {
673 mpc_set_prec(this->m_data, mpc_get_prec(val));
674 mpc_set(this->m_data, val, GMP_RNDN);
675 return *this;
676 }
677 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend678 mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
679 {
680 mpc_set_prec(this->m_data, mpc_get_prec(val.data()));
681 mpc_set(this->m_data, val.data(), GMP_RNDN);
682 return *this;
683 }
684 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend685 mpc_complex_backend& operator=(const mpfr_float_backend<D>& val)
686 {
687 mpc_set_prec(this->m_data, mpfr_get_prec(val.data()));
688 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
689 return *this;
690 }
operator =boost::multiprecision::backends::mpc_complex_backend691 mpc_complex_backend& operator=(const std::complex<float>& val)
692 {
693 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
694 return *this;
695 }
operator =boost::multiprecision::backends::mpc_complex_backend696 mpc_complex_backend& operator=(const std::complex<double>& val)
697 {
698 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
699 return *this;
700 }
operator =boost::multiprecision::backends::mpc_complex_backend701 mpc_complex_backend& operator=(const std::complex<long double>& val)
702 {
703 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
704 return *this;
705 }
default_precisionboost::multiprecision::backends::mpc_complex_backend706 static unsigned default_precision() BOOST_NOEXCEPT
707 {
708 return get_default_precision();
709 }
default_precisionboost::multiprecision::backends::mpc_complex_backend710 static void default_precision(unsigned v) BOOST_NOEXCEPT
711 {
712 get_default_precision() = v;
713 }
precisionboost::multiprecision::backends::mpc_complex_backend714 unsigned precision()const BOOST_NOEXCEPT
715 {
716 return multiprecision::detail::digits2_2_10(mpc_get_prec(this->m_data));
717 }
precisionboost::multiprecision::backends::mpc_complex_backend718 void precision(unsigned digits10) BOOST_NOEXCEPT
719 {
720 mpfr_prec_round(mpc_realref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
721 mpfr_prec_round(mpc_imagref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
722 }
723 };
724
725 template <unsigned digits10, class T>
eval_eq(const mpc_complex_backend<digits10> & a,const T & b)726 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
727 {
728 return a.compare(b) == 0;
729 }
730 template <unsigned digits10, class T>
eval_lt(const mpc_complex_backend<digits10> & a,const T & b)731 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
732 {
733 return a.compare(b) < 0;
734 }
735 template <unsigned digits10, class T>
eval_gt(const mpc_complex_backend<digits10> & a,const T & b)736 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
737 {
738 return a.compare(b) > 0;
739 }
740
741 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)742 inline void eval_add(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
743 {
744 mpc_add(result.data(), result.data(), o.data(), GMP_RNDD);
745 }
746 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)747 inline void eval_add(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
748 {
749 mpc_add_fr(result.data(), result.data(), o.data(), GMP_RNDD);
750 }
751 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)752 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
753 {
754 mpc_sub(result.data(), result.data(), o.data(), GMP_RNDD);
755 }
756 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)757 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
758 {
759 mpc_sub_fr(result.data(), result.data(), o.data(), GMP_RNDD);
760 }
761 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)762 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
763 {
764 if((void*)&result == (void*)&o)
765 mpc_sqr(result.data(), o.data(), GMP_RNDN);
766 else
767 mpc_mul(result.data(), result.data(), o.data(), GMP_RNDN);
768 }
769 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)770 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
771 {
772 mpc_mul_fr(result.data(), result.data(), o.data(), GMP_RNDN);
773 }
774 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)775 inline void eval_divide(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
776 {
777 mpc_div(result.data(), result.data(), o.data(), GMP_RNDD);
778 }
779 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)780 inline void eval_divide(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
781 {
782 mpc_div_fr(result.data(), result.data(), o.data(), GMP_RNDD);
783 }
784 template <unsigned digits10>
eval_add(mpc_complex_backend<digits10> & result,unsigned long i)785 inline void eval_add(mpc_complex_backend<digits10>& result, unsigned long i)
786 {
787 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
788 }
789 template <unsigned digits10>
eval_subtract(mpc_complex_backend<digits10> & result,unsigned long i)790 inline void eval_subtract(mpc_complex_backend<digits10>& result, unsigned long i)
791 {
792 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
793 }
794 template <unsigned digits10>
eval_multiply(mpc_complex_backend<digits10> & result,unsigned long i)795 inline void eval_multiply(mpc_complex_backend<digits10>& result, unsigned long i)
796 {
797 mpc_mul_ui(result.data(), result.data(), i, GMP_RNDN);
798 }
799 template <unsigned digits10>
eval_divide(mpc_complex_backend<digits10> & result,unsigned long i)800 inline void eval_divide(mpc_complex_backend<digits10>& result, unsigned long i)
801 {
802 mpc_div_ui(result.data(), result.data(), i, GMP_RNDN);
803 }
804 template <unsigned digits10>
eval_add(mpc_complex_backend<digits10> & result,long i)805 inline void eval_add(mpc_complex_backend<digits10>& result, long i)
806 {
807 if(i > 0)
808 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
809 else
810 mpc_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
811 }
812 template <unsigned digits10>
eval_subtract(mpc_complex_backend<digits10> & result,long i)813 inline void eval_subtract(mpc_complex_backend<digits10>& result, long i)
814 {
815 if(i > 0)
816 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
817 else
818 mpc_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
819 }
820 template <unsigned digits10>
eval_multiply(mpc_complex_backend<digits10> & result,long i)821 inline void eval_multiply(mpc_complex_backend<digits10>& result, long i)
822 {
823 mpc_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
824 if(i < 0)
825 mpc_neg(result.data(), result.data(), GMP_RNDN);
826 }
827 template <unsigned digits10>
eval_divide(mpc_complex_backend<digits10> & result,long i)828 inline void eval_divide(mpc_complex_backend<digits10>& result, long i)
829 {
830 mpc_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
831 if(i < 0)
832 mpc_neg(result.data(), result.data(), GMP_RNDN);
833 }
834 //
835 // Specialised 3 arg versions of the basic operators:
836 //
837 template <unsigned D1, unsigned D2, unsigned D3>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpc_complex_backend<D3> & y)838 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
839 {
840 mpc_add(a.data(), x.data(), y.data(), GMP_RNDD);
841 }
842 template <unsigned D1, unsigned D2, unsigned D3>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpfr_float_backend<D3> & y)843 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
844 {
845 mpc_add_fr(a.data(), x.data(), y.data(), GMP_RNDD);
846 }
847 template <unsigned D1, unsigned D2, unsigned D3>
eval_add(mpc_complex_backend<D1> & a,const mpfr_float_backend<D2> & x,const mpc_complex_backend<D3> & y)848 inline void eval_add(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
849 {
850 mpc_add_fr(a.data(), y.data(), x.data(), GMP_RNDD);
851 }
852 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)853 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
854 {
855 mpc_add_ui(a.data(), x.data(), y, GMP_RNDD);
856 }
857 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)858 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
859 {
860 if(y < 0)
861 mpc_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
862 else
863 mpc_add_ui(a.data(), x.data(), y, GMP_RNDD);
864 }
865 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)866 inline void eval_add(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
867 {
868 mpc_add_ui(a.data(), y.data(), x, GMP_RNDD);
869 }
870 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)871 inline void eval_add(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
872 {
873 if(x < 0)
874 {
875 mpc_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
876 mpc_neg(a.data(), a.data(), GMP_RNDD);
877 }
878 else
879 mpc_add_ui(a.data(), y.data(), x, GMP_RNDD);
880 }
881 template <unsigned D1, unsigned D2, unsigned D3>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpc_complex_backend<D3> & y)882 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
883 {
884 mpc_sub(a.data(), x.data(), y.data(), GMP_RNDD);
885 }
886 template <unsigned D1, unsigned D2, unsigned D3>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpfr_float_backend<D3> & y)887 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
888 {
889 mpc_sub_fr(a.data(), x.data(), y.data(), GMP_RNDD);
890 }
891 template <unsigned D1, unsigned D2, unsigned D3>
eval_subtract(mpc_complex_backend<D1> & a,const mpfr_float_backend<D2> & x,const mpc_complex_backend<D3> & y)892 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
893 {
894 mpc_fr_sub(a.data(), x.data(), y.data(), GMP_RNDD);
895 }
896 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)897 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
898 {
899 mpc_sub_ui(a.data(), x.data(), y, GMP_RNDD);
900 }
901 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)902 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
903 {
904 if(y < 0)
905 mpc_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
906 else
907 mpc_sub_ui(a.data(), x.data(), y, GMP_RNDD);
908 }
909 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)910 inline void eval_subtract(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
911 {
912 mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
913 }
914 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)915 inline void eval_subtract(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
916 {
917 if(x < 0)
918 {
919 mpc_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDD);
920 mpc_neg(a.data(), a.data(), GMP_RNDD);
921 }
922 else
923 mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
924 }
925
926 template <unsigned D1, unsigned D2, unsigned D3>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpc_complex_backend<D3> & y)927 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
928 {
929 if((void*)&x == (void*)&y)
930 mpc_sqr(a.data(), x.data(), GMP_RNDD);
931 else
932 mpc_mul(a.data(), x.data(), y.data(), GMP_RNDD);
933 }
934 template <unsigned D1, unsigned D2, unsigned D3>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpfr_float_backend<D3> & y)935 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
936 {
937 mpc_mul_fr(a.data(), x.data(), y.data(), GMP_RNDD);
938 }
939 template <unsigned D1, unsigned D2, unsigned D3>
eval_multiply(mpc_complex_backend<D1> & a,const mpfr_float_backend<D2> & x,const mpc_complex_backend<D3> & y)940 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
941 {
942 mpc_mul_fr(a.data(), y.data(), x.data(), GMP_RNDD);
943 }
944 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)945 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
946 {
947 mpc_mul_ui(a.data(), x.data(), y, GMP_RNDD);
948 }
949 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)950 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
951 {
952 if(y < 0)
953 {
954 mpc_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
955 a.negate();
956 }
957 else
958 mpc_mul_ui(a.data(), x.data(), y, GMP_RNDD);
959 }
960 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)961 inline void eval_multiply(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
962 {
963 mpc_mul_ui(a.data(), y.data(), x, GMP_RNDD);
964 }
965 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)966 inline void eval_multiply(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
967 {
968 if(x < 0)
969 {
970 mpc_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDD);
971 mpc_neg(a.data(), a.data(), GMP_RNDD);
972 }
973 else
974 mpc_mul_ui(a.data(), y.data(), x, GMP_RNDD);
975 }
976
977 template <unsigned D1, unsigned D2, unsigned D3>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpc_complex_backend<D3> & y)978 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
979 {
980 mpc_div(a.data(), x.data(), y.data(), GMP_RNDD);
981 }
982 template <unsigned D1, unsigned D2, unsigned D3>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpfr_float_backend<D3> & y)983 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
984 {
985 mpc_div_fr(a.data(), x.data(), y.data(), GMP_RNDD);
986 }
987 template <unsigned D1, unsigned D2, unsigned D3>
eval_divide(mpc_complex_backend<D1> & a,const mpfr_float_backend<D2> & x,const mpc_complex_backend<D3> & y)988 inline void eval_divide(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
989 {
990 mpc_fr_div(a.data(), x.data(), y.data(), GMP_RNDD);
991 }
992 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)993 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
994 {
995 mpc_div_ui(a.data(), x.data(), y, GMP_RNDD);
996 }
997 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)998 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
999 {
1000 if(y < 0)
1001 {
1002 mpc_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
1003 a.negate();
1004 }
1005 else
1006 mpc_div_ui(a.data(), x.data(), y, GMP_RNDD);
1007 }
1008 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)1009 inline void eval_divide(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
1010 {
1011 mpc_ui_div(a.data(), x, y.data(), GMP_RNDD);
1012 }
1013 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)1014 inline void eval_divide(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
1015 {
1016 if(x < 0)
1017 {
1018 mpc_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDD);
1019 mpc_neg(a.data(), a.data(), GMP_RNDD);
1020 }
1021 else
1022 mpc_ui_div(a.data(), x, y.data(), GMP_RNDD);
1023 }
1024
1025 template <unsigned digits10>
eval_is_zero(const mpc_complex_backend<digits10> & val)1026 inline bool eval_is_zero(const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1027 {
1028 return (0 != mpfr_zero_p(mpc_realref(val.data()))) && (0 != mpfr_zero_p(mpc_imagref(val.data())));
1029 }
1030 template <unsigned digits10>
eval_get_sign(const mpc_complex_backend<digits10> &)1031 inline int eval_get_sign(const mpc_complex_backend<digits10>&)
1032 {
1033 BOOST_STATIC_ASSERT_MSG(digits10 == UINT_MAX, "Complex numbers have no sign bit."); // designed to always fail
1034 return 0;
1035 }
1036
1037 template <unsigned digits10>
eval_convert_to(unsigned long * result,const mpc_complex_backend<digits10> & val)1038 inline void eval_convert_to(unsigned long* result, const mpc_complex_backend<digits10>& val)
1039 {
1040 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1041 {
1042 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1043 }
1044 mpfr_float_backend<digits10> t;
1045 mpc_real(t.data(), val.data(), GMP_RNDN);
1046 eval_convert_to(result, t);
1047 }
1048 template <unsigned digits10>
eval_convert_to(long * result,const mpc_complex_backend<digits10> & val)1049 inline void eval_convert_to(long* result, const mpc_complex_backend<digits10>& val)
1050 {
1051 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1052 {
1053 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1054 }
1055 mpfr_float_backend<digits10> t;
1056 mpc_real(t.data(), val.data(), GMP_RNDN);
1057 eval_convert_to(result, t);
1058 }
1059 #ifdef _MPFR_H_HAVE_INTMAX_T
1060 template <unsigned digits10>
eval_convert_to(boost::ulong_long_type * result,const mpc_complex_backend<digits10> & val)1061 inline void eval_convert_to(boost::ulong_long_type* result, const mpc_complex_backend<digits10>& val)
1062 {
1063 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1064 {
1065 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1066 }
1067 mpfr_float_backend<digits10> t;
1068 mpc_real(t.data(), val.data(), GMP_RNDN);
1069 eval_convert_to(result, t);
1070 }
1071 template <unsigned digits10>
eval_convert_to(boost::long_long_type * result,const mpc_complex_backend<digits10> & val)1072 inline void eval_convert_to(boost::long_long_type* result, const mpc_complex_backend<digits10>& val)
1073 {
1074 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1075 {
1076 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1077 }
1078 mpfr_float_backend<digits10> t;
1079 mpc_real(t.data(), val.data(), GMP_RNDN);
1080 eval_convert_to(result, t);
1081 }
1082 #endif
1083 template <unsigned digits10>
eval_convert_to(double * result,const mpc_complex_backend<digits10> & val)1084 inline void eval_convert_to(double* result, const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1085 {
1086 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1087 {
1088 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1089 }
1090 mpfr_float_backend<digits10> t;
1091 mpc_real(t.data(), val.data(), GMP_RNDN);
1092 eval_convert_to(result, t);
1093 }
1094 template <unsigned digits10>
eval_convert_to(long double * result,const mpc_complex_backend<digits10> & val)1095 inline void eval_convert_to(long double* result, const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1096 {
1097 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1098 {
1099 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1100 }
1101 mpfr_float_backend<digits10> t;
1102 mpc_real(t.data(), val.data(), GMP_RNDN);
1103 eval_convert_to(result, t);
1104 }
1105
1106 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2,AllocationType> & a,const mpfr_float_backend<D2,AllocationType> & b)1107 inline void assign_components(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
1108 {
1109 //
1110 // This is called from class number's constructors, so if we have variable
1111 // precision, then copy the precision of the source variables.
1112 //
1113 if (!D1)
1114 {
1115 unsigned long prec = std::max(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
1116 mpc_set_prec(result.data(), prec);
1117 }
1118 using default_ops::eval_fpclassify;
1119 if(eval_fpclassify(a) == (int)FP_NAN)
1120 {
1121 mpc_set_fr(result.data(), a.data(), GMP_RNDN);
1122 }
1123 else if(eval_fpclassify(b) == (int)FP_NAN)
1124 {
1125 mpc_set_fr(result.data(), b.data(), GMP_RNDN);
1126 }
1127 else
1128 {
1129 mpc_set_fr_fr(result.data(), a.data(), b.data(), GMP_RNDN);
1130 }
1131 }
1132
1133 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,unsigned long a,unsigned long b)1134 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long a, unsigned long b)
1135 {
1136 mpc_set_ui_ui(result.data(), a, b, GMP_RNDN);
1137 }
1138
1139 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long a,long b)1140 inline void assign_components(mpc_complex_backend<D1>& result, long a, long b)
1141 {
1142 mpc_set_si_si(result.data(), a, b, GMP_RNDN);
1143 }
1144
1145 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1146 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,unsigned long long a,unsigned long long b)1147 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long long a, unsigned long long b)
1148 {
1149 mpc_set_uj_uj(result.data(), a, b, GMP_RNDN);
1150 }
1151
1152 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long long a,long long b)1153 inline void assign_components(mpc_complex_backend<D1>& result, long long a, long long b)
1154 {
1155 mpc_set_sj_sj(result.data(), a, b, GMP_RNDN);
1156 }
1157 #endif
1158
1159 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,double a,double b)1160 inline void assign_components(mpc_complex_backend<D1>& result, double a, double b)
1161 {
1162 if ((boost::math::isnan)(a))
1163 {
1164 mpc_set_d(result.data(), a, GMP_RNDN);
1165 }
1166 else if ((boost::math::isnan)(b))
1167 {
1168 mpc_set_d(result.data(), b, GMP_RNDN);
1169 }
1170 else
1171 {
1172 mpc_set_d_d(result.data(), a, b, GMP_RNDN);
1173 }
1174 }
1175
1176 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long double a,long double b)1177 inline void assign_components(mpc_complex_backend<D1>& result, long double a, long double b)
1178 {
1179 if ((boost::math::isnan)(a))
1180 {
1181 mpc_set_d(result.data(), a, GMP_RNDN);
1182 }
1183 else if ((boost::math::isnan)(b))
1184 {
1185 mpc_set_d(result.data(), b, GMP_RNDN);
1186 }
1187 else
1188 {
1189 mpc_set_ld_ld(result.data(), a, b, GMP_RNDN);
1190 }
1191 }
1192
1193 //
1194 // Native non-member operations:
1195 //
1196 template <unsigned Digits10>
eval_sqrt(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & val)1197 inline void eval_sqrt(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& val)
1198 {
1199 mpc_sqrt(result.data(), val.data(), GMP_RNDN);
1200 }
1201
1202 template <unsigned Digits10>
eval_pow(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & b,const mpc_complex_backend<Digits10> & e)1203 inline void eval_pow(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& b, const mpc_complex_backend<Digits10>& e)
1204 {
1205 mpc_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1206 }
1207
1208 template <unsigned Digits10>
eval_exp(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1209 inline void eval_exp(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1210 {
1211 mpc_exp(result.data(), arg.data(), GMP_RNDN);
1212 }
1213
1214 template <unsigned Digits10>
eval_log(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1215 inline void eval_log(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1216 {
1217 mpc_log(result.data(), arg.data(), GMP_RNDN);
1218 }
1219
1220 template <unsigned Digits10>
eval_log10(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1221 inline void eval_log10(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1222 {
1223 mpc_log10(result.data(), arg.data(), GMP_RNDN);
1224 }
1225
1226 template <unsigned Digits10>
eval_sin(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1227 inline void eval_sin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1228 {
1229 mpc_sin(result.data(), arg.data(), GMP_RNDN);
1230 }
1231
1232 template <unsigned Digits10>
eval_cos(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1233 inline void eval_cos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1234 {
1235 mpc_cos(result.data(), arg.data(), GMP_RNDN);
1236 }
1237
1238 template <unsigned Digits10>
eval_tan(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1239 inline void eval_tan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1240 {
1241 mpc_tan(result.data(), arg.data(), GMP_RNDN);
1242 }
1243
1244 template <unsigned Digits10>
eval_asin(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1245 inline void eval_asin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1246 {
1247 mpc_asin(result.data(), arg.data(), GMP_RNDN);
1248 }
1249
1250 template <unsigned Digits10>
eval_acos(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1251 inline void eval_acos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1252 {
1253 mpc_acos(result.data(), arg.data(), GMP_RNDN);
1254 }
1255
1256 template <unsigned Digits10>
eval_atan(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1257 inline void eval_atan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1258 {
1259 mpc_atan(result.data(), arg.data(), GMP_RNDN);
1260 }
1261
1262 template <unsigned Digits10>
eval_sinh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1263 inline void eval_sinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1264 {
1265 mpc_sinh(result.data(), arg.data(), GMP_RNDN);
1266 }
1267
1268 template <unsigned Digits10>
eval_cosh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1269 inline void eval_cosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1270 {
1271 mpc_cosh(result.data(), arg.data(), GMP_RNDN);
1272 }
1273
1274 template <unsigned Digits10>
eval_tanh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1275 inline void eval_tanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1276 {
1277 mpc_tanh(result.data(), arg.data(), GMP_RNDN);
1278 }
1279
1280 template <unsigned Digits10>
eval_asinh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1281 inline void eval_asinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1282 {
1283 mpc_asinh(result.data(), arg.data(), GMP_RNDN);
1284 }
1285
1286 template <unsigned Digits10>
eval_acosh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1287 inline void eval_acosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1288 {
1289 mpc_acosh(result.data(), arg.data(), GMP_RNDN);
1290 }
1291
1292 template <unsigned Digits10>
eval_atanh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1293 inline void eval_atanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1294 {
1295 mpc_atanh(result.data(), arg.data(), GMP_RNDN);
1296 }
1297
1298 template <unsigned Digits10>
eval_conj(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1299 inline void eval_conj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1300 {
1301 mpc_conj(result.data(), arg.data(), GMP_RNDN);
1302 }
1303
1304 template <unsigned Digits10>
eval_proj(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1305 inline void eval_proj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1306 {
1307 mpc_proj(result.data(), arg.data(), GMP_RNDN);
1308 }
1309
1310 template <unsigned Digits10>
eval_real(mpfr_float_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1311 inline void eval_real(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1312 {
1313 mpfr_set_prec(result.data(), mpfr_get_prec(mpc_realref(arg.data())));
1314 mpfr_set(result.data(), mpc_realref(arg.data()), GMP_RNDN);
1315 }
1316 template <unsigned Digits10>
eval_imag(mpfr_float_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1317 inline void eval_imag(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1318 {
1319 mpfr_set_prec(result.data(), mpfr_get_prec(mpc_imagref(arg.data())));
1320 mpfr_set(result.data(), mpc_imagref(arg.data()), GMP_RNDN);
1321 }
1322
1323 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const mpfr_float_backend<Digits10> & arg)1324 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1325 {
1326 mpfr_set(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1327 }
1328
1329 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const mpfr_float_backend<Digits10> & arg)1330 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1331 {
1332 mpfr_set(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1333 }
1334 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const gmp_int & arg)1335 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1336 {
1337 mpfr_set_z(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1338 }
1339 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const gmp_rational & arg)1340 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1341 {
1342 mpfr_set_q(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1343 }
1344 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned & arg)1345 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1346 {
1347 mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1348 }
1349 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned long & arg)1350 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1351 {
1352 mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1353 }
1354 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const int & arg)1355 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const int& arg)
1356 {
1357 mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1358 }
1359 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long & arg)1360 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long& arg)
1361 {
1362 mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1363 }
1364 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const float & arg)1365 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const float& arg)
1366 {
1367 mpfr_set_flt(mpc_realref(result.data()), arg, GMP_RNDN);
1368 }
1369 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const double & arg)1370 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const double& arg)
1371 {
1372 mpfr_set_d(mpc_realref(result.data()), arg, GMP_RNDN);
1373 }
1374 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long double & arg)1375 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long double& arg)
1376 {
1377 mpfr_set_ld(mpc_realref(result.data()), arg, GMP_RNDN);
1378 }
1379 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1380 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned long long & arg)1381 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1382 {
1383 mpfr_set_uj(mpc_realref(result.data()), arg, GMP_RNDN);
1384 }
1385 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long long & arg)1386 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long long& arg)
1387 {
1388 mpfr_set_sj(mpc_realref(result.data()), arg, GMP_RNDN);
1389 }
1390 #endif
1391
1392 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const gmp_int & arg)1393 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1394 {
1395 mpfr_set_z(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1396 }
1397 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const gmp_rational & arg)1398 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1399 {
1400 mpfr_set_q(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1401 }
1402 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned & arg)1403 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1404 {
1405 mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1406 }
1407 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned long & arg)1408 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1409 {
1410 mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1411 }
1412 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const int & arg)1413 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const int& arg)
1414 {
1415 mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1416 }
1417 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long & arg)1418 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long& arg)
1419 {
1420 mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1421 }
1422 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const float & arg)1423 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const float& arg)
1424 {
1425 mpfr_set_flt(mpc_imagref(result.data()), arg, GMP_RNDN);
1426 }
1427 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const double & arg)1428 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const double& arg)
1429 {
1430 mpfr_set_d(mpc_imagref(result.data()), arg, GMP_RNDN);
1431 }
1432 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long double & arg)1433 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long double& arg)
1434 {
1435 mpfr_set_ld(mpc_imagref(result.data()), arg, GMP_RNDN);
1436 }
1437 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1438 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned long long & arg)1439 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1440 {
1441 mpfr_set_uj(mpc_imagref(result.data()), arg, GMP_RNDN);
1442 }
1443 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long long & arg)1444 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long long& arg)
1445 {
1446 mpfr_set_sj(mpc_imagref(result.data()), arg, GMP_RNDN);
1447 }
1448 #endif
1449
1450 template <unsigned Digits10>
hash_value(const mpc_complex_backend<Digits10> & val)1451 inline std::size_t hash_value(const mpc_complex_backend<Digits10>& val)
1452 {
1453 std::size_t result = 0;
1454 std::size_t len = val.data()[0].re[0]._mpfr_prec / mp_bits_per_limb;
1455 if(val.data()[0].re[0]._mpfr_prec % mp_bits_per_limb)
1456 ++len;
1457 for(std::size_t i = 0; i < len; ++i)
1458 boost::hash_combine(result, val.data()[0].re[0]._mpfr_d[i]);
1459 boost::hash_combine(result, val.data()[0].re[0]._mpfr_exp);
1460 boost::hash_combine(result, val.data()[0].re[0]._mpfr_sign);
1461
1462 len = val.data()[0].im[0]._mpfr_prec / mp_bits_per_limb;
1463 if(val.data()[0].im[0]._mpfr_prec % mp_bits_per_limb)
1464 ++len;
1465 for(std::size_t i = 0; i < len; ++i)
1466 boost::hash_combine(result, val.data()[0].im[0]._mpfr_d[i]);
1467 boost::hash_combine(result, val.data()[0].im[0]._mpfr_exp);
1468 boost::hash_combine(result, val.data()[0].im[0]._mpfr_sign);
1469 return result;
1470 }
1471
1472 } // namespace backends
1473
1474 #ifdef BOOST_NO_SFINAE_EXPR
1475
1476 namespace detail{
1477
1478 template<unsigned D1, unsigned D2>
1479 struct is_explicitly_convertible<backends::mpc_complex_backend<D1>, backends::mpc_complex_backend<D2> > : public mpl::true_ {};
1480
1481 }
1482 #endif
1483
1484 namespace detail
1485 {
1486 template<>
1487 struct is_variable_precision<backends::mpc_complex_backend<0> > : public true_type {};
1488 }
1489
1490 template<>
1491 struct number_category<detail::canonical<mpc_t, backends::mpc_complex_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
1492
1493 using boost::multiprecision::backends::mpc_complex_backend;
1494
1495 typedef number<mpc_complex_backend<50> > mpc_complex_50;
1496 typedef number<mpc_complex_backend<100> > mpc_complex_100;
1497 typedef number<mpc_complex_backend<500> > mpc_complex_500;
1498 typedef number<mpc_complex_backend<1000> > mpc_complex_1000;
1499 typedef number<mpc_complex_backend<0> > mpc_complex;
1500
1501 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1502 struct component_type<number<mpc_complex_backend<Digits10>, ExpressionTemplates> >
1503 {
1504 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1505 };
1506
1507 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1508 struct component_type<number<logged_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> >
1509 {
1510 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1511 };
1512
1513 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1514 struct complex_result_from_scalar<number<mpfr_float_backend<Digits10>, ExpressionTemplates> >
1515 {
1516 typedef number<mpc_complex_backend<Digits10>, ExpressionTemplates> type;
1517 };
1518
1519 } // namespace multiprecision
1520
1521 } // namespaces
1522
1523 #endif
1524