mpc.hpp 50 KB

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