mpc.hpp 50 KB

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