mpc.hpp 43 KB

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