mpc.hpp 50 KB

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