mpfr.hpp 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2011 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_MATH_BN_MPFR_HPP
  6. #define BOOST_MATH_BN_MPFR_HPP
  7. #include <boost/multiprecision/number.hpp>
  8. #include <boost/multiprecision/gmp.hpp>
  9. #include <boost/math/special_functions/fpclassify.hpp>
  10. #include <boost/cstdint.hpp>
  11. #include <boost/multiprecision/detail/big_lanczos.hpp>
  12. #include <boost/multiprecision/detail/digits.hpp>
  13. #include <mpfr.h>
  14. #include <cmath>
  15. #include <algorithm>
  16. namespace boost{
  17. namespace multiprecision{
  18. enum mpfr_allocation_type
  19. {
  20. allocate_stack,
  21. allocate_dynamic
  22. };
  23. namespace backends{
  24. template <unsigned digits10, mpfr_allocation_type AllocationType = allocate_dynamic>
  25. struct mpfr_float_backend;
  26. } // namespace backends
  27. template <unsigned digits10, mpfr_allocation_type AllocationType>
  28. struct number_category<backends::mpfr_float_backend<digits10, AllocationType> > : public mpl::int_<number_kind_floating_point>{};
  29. namespace backends{
  30. namespace detail{
  31. template <bool b>
  32. struct mpfr_cleanup
  33. {
  34. struct initializer
  35. {
  36. initializer() {}
  37. ~initializer(){ mpfr_free_cache(); }
  38. void force_instantiate()const {}
  39. };
  40. static const initializer init;
  41. static void force_instantiate() { init.force_instantiate(); }
  42. };
  43. template <bool b>
  44. typename mpfr_cleanup<b>::initializer const mpfr_cleanup<b>::init;
  45. inline long get_default_precision() { return 50; }
  46. template <unsigned digits10, mpfr_allocation_type AllocationType>
  47. struct mpfr_float_imp;
  48. template <unsigned digits10>
  49. struct mpfr_float_imp<digits10, allocate_dynamic>
  50. {
  51. typedef mpl::list<long, long long> signed_types;
  52. typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
  53. typedef mpl::list<double, long double> float_types;
  54. typedef long exponent_type;
  55. mpfr_float_imp()
  56. {
  57. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  58. }
  59. mpfr_float_imp(unsigned prec)
  60. {
  61. mpfr_init2(m_data, prec);
  62. }
  63. mpfr_float_imp(const mpfr_float_imp& o)
  64. {
  65. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  66. if(o.m_data[0]._mpfr_d)
  67. mpfr_set(m_data, o.m_data, GMP_RNDN);
  68. }
  69. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  70. mpfr_float_imp(mpfr_float_imp&& o) BOOST_NOEXCEPT
  71. {
  72. m_data[0] = o.m_data[0];
  73. o.m_data[0]._mpfr_d = 0;
  74. }
  75. #endif
  76. mpfr_float_imp& operator = (const mpfr_float_imp& o)
  77. {
  78. if(m_data[0]._mpfr_d == 0)
  79. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  80. if(o.m_data[0]._mpfr_d)
  81. mpfr_set(m_data, o.m_data, GMP_RNDN);
  82. return *this;
  83. }
  84. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  85. mpfr_float_imp& operator = (mpfr_float_imp&& o) BOOST_NOEXCEPT
  86. {
  87. mpfr_swap(m_data, o.m_data);
  88. return *this;
  89. }
  90. #endif
  91. #ifdef _MPFR_H_HAVE_INTMAX_T
  92. mpfr_float_imp& operator = (unsigned long long i)
  93. {
  94. if(m_data[0]._mpfr_d == 0)
  95. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  96. mpfr_set_uj(m_data, i, GMP_RNDN);
  97. return *this;
  98. }
  99. mpfr_float_imp& operator = (long long i)
  100. {
  101. if(m_data[0]._mpfr_d == 0)
  102. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  103. mpfr_set_sj(m_data, i, GMP_RNDN);
  104. return *this;
  105. }
  106. #else
  107. mpfr_float_imp& operator = (unsigned long long i)
  108. {
  109. if(m_data[0]._mpfr_d == 0)
  110. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  111. unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
  112. unsigned shift = 0;
  113. mpfr_t t;
  114. mpfr_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
  115. mpfr_set_ui(m_data, 0, GMP_RNDN);
  116. while(i)
  117. {
  118. mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
  119. if(shift)
  120. mpfr_mul_2exp(t, t, shift, GMP_RNDN);
  121. mpfr_add(m_data, m_data, t, GMP_RNDN);
  122. shift += std::numeric_limits<unsigned>::digits;
  123. i >>= std::numeric_limits<unsigned>::digits;
  124. }
  125. mpfr_clear(t);
  126. return *this;
  127. }
  128. mpfr_float_imp& operator = (long long i)
  129. {
  130. BOOST_MP_USING_ABS
  131. if(m_data[0]._mpfr_d == 0)
  132. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  133. bool neg = i < 0;
  134. *this = static_cast<unsigned long long>(abs(i));
  135. if(neg)
  136. mpfr_neg(m_data, m_data, GMP_RNDN);
  137. return *this;
  138. }
  139. #endif
  140. mpfr_float_imp& operator = (unsigned long i)
  141. {
  142. if(m_data[0]._mpfr_d == 0)
  143. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  144. mpfr_set_ui(m_data, i, GMP_RNDN);
  145. return *this;
  146. }
  147. mpfr_float_imp& operator = (long i)
  148. {
  149. if(m_data[0]._mpfr_d == 0)
  150. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  151. mpfr_set_si(m_data, i, GMP_RNDN);
  152. return *this;
  153. }
  154. mpfr_float_imp& operator = (double d)
  155. {
  156. if(m_data[0]._mpfr_d == 0)
  157. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  158. mpfr_set_d(m_data, d, GMP_RNDN);
  159. return *this;
  160. }
  161. mpfr_float_imp& operator = (long double a)
  162. {
  163. if(m_data[0]._mpfr_d == 0)
  164. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  165. mpfr_set_ld(m_data, a, GMP_RNDN);
  166. return *this;
  167. }
  168. mpfr_float_imp& operator = (const char* s)
  169. {
  170. if(m_data[0]._mpfr_d == 0)
  171. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  172. if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
  173. {
  174. BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
  175. }
  176. return *this;
  177. }
  178. void swap(mpfr_float_imp& o) BOOST_NOEXCEPT
  179. {
  180. mpfr_swap(m_data, o.m_data);
  181. }
  182. std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
  183. {
  184. BOOST_ASSERT(m_data[0]._mpfr_d);
  185. bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
  186. bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
  187. std::streamsize org_digits(digits);
  188. if(scientific && digits)
  189. ++digits;
  190. std::string result;
  191. mp_exp_t e;
  192. if(mpfr_inf_p(m_data))
  193. {
  194. if(mpfr_sgn(m_data) < 0)
  195. result = "-inf";
  196. else if(f & std::ios_base::showpos)
  197. result = "+inf";
  198. else
  199. result = "inf";
  200. return result;
  201. }
  202. if(mpfr_nan_p(m_data))
  203. {
  204. result = "nan";
  205. return result;
  206. }
  207. if(mpfr_zero_p(m_data))
  208. {
  209. e = 0;
  210. result = "0";
  211. }
  212. else
  213. {
  214. char* ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  215. --e; // To match with what our formatter expects.
  216. if(fixed && e != -1)
  217. {
  218. // Oops we actually need a different number of digits to what we asked for:
  219. mpfr_free_str(ps);
  220. digits += e + 1;
  221. if(digits == 0)
  222. {
  223. // We need to get *all* the digits and then possibly round up,
  224. // we end up with either "0" or "1" as the result.
  225. ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN);
  226. --e;
  227. unsigned offset = *ps == '-' ? 1 : 0;
  228. if(ps[offset] > '5')
  229. {
  230. ++e;
  231. ps[offset] = '1';
  232. ps[offset + 1] = 0;
  233. }
  234. else if(ps[offset] == '5')
  235. {
  236. unsigned i = offset + 1;
  237. bool round_up = false;
  238. while(ps[i] != 0)
  239. {
  240. if(ps[i] != '0')
  241. {
  242. round_up = true;
  243. break;
  244. }
  245. }
  246. if(round_up)
  247. {
  248. ++e;
  249. ps[offset] = '1';
  250. ps[offset + 1] = 0;
  251. }
  252. else
  253. {
  254. ps[offset] = '0';
  255. ps[offset + 1] = 0;
  256. }
  257. }
  258. else
  259. {
  260. ps[offset] = '0';
  261. ps[offset + 1] = 0;
  262. }
  263. }
  264. else if(digits > 0)
  265. {
  266. ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  267. --e; // To match with what our formatter expects.
  268. }
  269. else
  270. {
  271. ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN);
  272. --e;
  273. unsigned offset = *ps == '-' ? 1 : 0;
  274. ps[offset] = '0';
  275. ps[offset + 1] = 0;
  276. }
  277. }
  278. result = ps ? ps : "0";
  279. if(ps)
  280. mpfr_free_str(ps);
  281. }
  282. boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
  283. return result;
  284. }
  285. ~mpfr_float_imp() BOOST_NOEXCEPT
  286. {
  287. if(m_data[0]._mpfr_d)
  288. mpfr_clear(m_data);
  289. detail::mpfr_cleanup<true>::force_instantiate();
  290. }
  291. void negate() BOOST_NOEXCEPT
  292. {
  293. BOOST_ASSERT(m_data[0]._mpfr_d);
  294. mpfr_neg(m_data, m_data, GMP_RNDN);
  295. }
  296. template <mpfr_allocation_type AllocationType>
  297. int compare(const mpfr_float_backend<digits10, AllocationType>& o)const BOOST_NOEXCEPT
  298. {
  299. BOOST_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d);
  300. return mpfr_cmp(m_data, o.m_data);
  301. }
  302. int compare(long i)const BOOST_NOEXCEPT
  303. {
  304. BOOST_ASSERT(m_data[0]._mpfr_d);
  305. return mpfr_cmp_si(m_data, i);
  306. }
  307. int compare(unsigned long i)const BOOST_NOEXCEPT
  308. {
  309. BOOST_ASSERT(m_data[0]._mpfr_d);
  310. return mpfr_cmp_ui(m_data, i);
  311. }
  312. template <class V>
  313. int compare(V v)const BOOST_NOEXCEPT
  314. {
  315. mpfr_float_backend<digits10, allocate_dynamic> d;
  316. d = v;
  317. return compare(d);
  318. }
  319. mpfr_t& data() BOOST_NOEXCEPT
  320. {
  321. BOOST_ASSERT(m_data[0]._mpfr_d);
  322. return m_data;
  323. }
  324. const mpfr_t& data()const BOOST_NOEXCEPT
  325. {
  326. BOOST_ASSERT(m_data[0]._mpfr_d);
  327. return m_data;
  328. }
  329. protected:
  330. mpfr_t m_data;
  331. static unsigned& get_default_precision() BOOST_NOEXCEPT
  332. {
  333. static unsigned val = 50;
  334. return val;
  335. }
  336. };
  337. #ifdef BOOST_MSVC
  338. #pragma warning(push)
  339. #pragma warning(disable:4127) // Conditional expression is constant
  340. #endif
  341. template <unsigned digits10>
  342. struct mpfr_float_imp<digits10, allocate_stack>
  343. {
  344. typedef mpl::list<long, long long> signed_types;
  345. typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
  346. typedef mpl::list<double, long double> float_types;
  347. typedef long exponent_type;
  348. static const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u);
  349. static const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t);
  350. ~mpfr_float_imp() BOOST_NOEXCEPT
  351. {
  352. detail::mpfr_cleanup<true>::force_instantiate();
  353. }
  354. mpfr_float_imp()
  355. {
  356. mpfr_custom_init(m_buffer, digits2);
  357. mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
  358. }
  359. mpfr_float_imp(const mpfr_float_imp& o)
  360. {
  361. mpfr_custom_init(m_buffer, digits2);
  362. mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
  363. mpfr_set(m_data, o.m_data, GMP_RNDN);
  364. }
  365. mpfr_float_imp& operator = (const mpfr_float_imp& o)
  366. {
  367. mpfr_set(m_data, o.m_data, GMP_RNDN);
  368. return *this;
  369. }
  370. #ifdef _MPFR_H_HAVE_INTMAX_T
  371. mpfr_float_imp& operator = (unsigned long long i)
  372. {
  373. mpfr_set_uj(m_data, i, GMP_RNDN);
  374. return *this;
  375. }
  376. mpfr_float_imp& operator = (long long i)
  377. {
  378. mpfr_set_sj(m_data, i, GMP_RNDN);
  379. return *this;
  380. }
  381. #else
  382. mpfr_float_imp& operator = (unsigned long long i)
  383. {
  384. unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
  385. unsigned shift = 0;
  386. mpfr_t t;
  387. mp_limb_t t_limbs[limb_count];
  388. mpfr_custom_init(t_limbs, digits2);
  389. mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
  390. mpfr_set_ui(m_data, 0, GMP_RNDN);
  391. while(i)
  392. {
  393. mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
  394. if(shift)
  395. mpfr_mul_2exp(t, t, shift, GMP_RNDN);
  396. mpfr_add(m_data, m_data, t, GMP_RNDN);
  397. shift += std::numeric_limits<unsigned>::digits;
  398. i >>= std::numeric_limits<unsigned>::digits;
  399. }
  400. return *this;
  401. }
  402. mpfr_float_imp& operator = (long long i)
  403. {
  404. BOOST_MP_USING_ABS
  405. bool neg = i < 0;
  406. *this = static_cast<unsigned long long>(abs(i));
  407. if(neg)
  408. mpfr_neg(m_data, m_data, GMP_RNDN);
  409. return *this;
  410. }
  411. #endif
  412. mpfr_float_imp& operator = (unsigned long i)
  413. {
  414. mpfr_set_ui(m_data, i, GMP_RNDN);
  415. return *this;
  416. }
  417. mpfr_float_imp& operator = (long i)
  418. {
  419. mpfr_set_si(m_data, i, GMP_RNDN);
  420. return *this;
  421. }
  422. mpfr_float_imp& operator = (double d)
  423. {
  424. mpfr_set_d(m_data, d, GMP_RNDN);
  425. return *this;
  426. }
  427. mpfr_float_imp& operator = (long double a)
  428. {
  429. mpfr_set_ld(m_data, a, GMP_RNDN);
  430. return *this;
  431. }
  432. mpfr_float_imp& operator = (const char* s)
  433. {
  434. if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
  435. {
  436. BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
  437. }
  438. return *this;
  439. }
  440. void swap(mpfr_float_imp& o) BOOST_NOEXCEPT
  441. {
  442. // We have to swap by copying:
  443. mpfr_float_imp t(*this);
  444. *this = o;
  445. o = t;
  446. }
  447. std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
  448. {
  449. BOOST_ASSERT(m_data[0]._mpfr_d);
  450. bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
  451. bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
  452. std::streamsize org_digits(digits);
  453. if(scientific && digits)
  454. ++digits;
  455. std::string result;
  456. mp_exp_t e;
  457. if(mpfr_inf_p(m_data))
  458. {
  459. if(mpfr_sgn(m_data) < 0)
  460. result = "-inf";
  461. else if(f & std::ios_base::showpos)
  462. result = "+inf";
  463. else
  464. result = "inf";
  465. return result;
  466. }
  467. if(mpfr_nan_p(m_data))
  468. {
  469. result = "nan";
  470. return result;
  471. }
  472. if(mpfr_zero_p(m_data))
  473. {
  474. e = 0;
  475. result = "0";
  476. }
  477. else
  478. {
  479. char* ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  480. --e; // To match with what our formatter expects.
  481. if(fixed && e != -1)
  482. {
  483. // Oops we actually need a different number of digits to what we asked for:
  484. mpfr_free_str(ps);
  485. digits += e + 1;
  486. if(digits == 0)
  487. {
  488. // We need to get *all* the digits and then possibly round up,
  489. // we end up with either "0" or "1" as the result.
  490. ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN);
  491. --e;
  492. unsigned offset = *ps == '-' ? 1 : 0;
  493. if(ps[offset] > '5')
  494. {
  495. ++e;
  496. ps[offset] = '1';
  497. ps[offset + 1] = 0;
  498. }
  499. else if(ps[offset] == '5')
  500. {
  501. unsigned i = offset + 1;
  502. bool round_up = false;
  503. while(ps[i] != 0)
  504. {
  505. if(ps[i] != '0')
  506. {
  507. round_up = true;
  508. break;
  509. }
  510. }
  511. if(round_up)
  512. {
  513. ++e;
  514. ps[offset] = '1';
  515. ps[offset + 1] = 0;
  516. }
  517. else
  518. {
  519. ps[offset] = '0';
  520. ps[offset + 1] = 0;
  521. }
  522. }
  523. else
  524. {
  525. ps[offset] = '0';
  526. ps[offset + 1] = 0;
  527. }
  528. }
  529. else if(digits > 0)
  530. {
  531. ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  532. --e; // To match with what our formatter expects.
  533. }
  534. else
  535. {
  536. ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN);
  537. --e;
  538. unsigned offset = *ps == '-' ? 1 : 0;
  539. ps[offset] = '0';
  540. ps[offset + 1] = 0;
  541. }
  542. }
  543. result = ps ? ps : "0";
  544. if(ps)
  545. mpfr_free_str(ps);
  546. }
  547. boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
  548. return result;
  549. }
  550. void negate() BOOST_NOEXCEPT
  551. {
  552. mpfr_neg(m_data, m_data, GMP_RNDN);
  553. }
  554. template <mpfr_allocation_type AllocationType>
  555. int compare(const mpfr_float_backend<digits10, AllocationType>& o)const BOOST_NOEXCEPT
  556. {
  557. return mpfr_cmp(m_data, o.m_data);
  558. }
  559. int compare(long i)const BOOST_NOEXCEPT
  560. {
  561. return mpfr_cmp_si(m_data, i);
  562. }
  563. int compare(unsigned long i)const BOOST_NOEXCEPT
  564. {
  565. return mpfr_cmp_ui(m_data, i);
  566. }
  567. template <class V>
  568. int compare(V v)const BOOST_NOEXCEPT
  569. {
  570. mpfr_float_backend<digits10, allocate_stack> d;
  571. d = v;
  572. return compare(d);
  573. }
  574. mpfr_t& data() BOOST_NOEXCEPT
  575. {
  576. return m_data;
  577. }
  578. const mpfr_t& data()const BOOST_NOEXCEPT
  579. {
  580. return m_data;
  581. }
  582. protected:
  583. mpfr_t m_data;
  584. mp_limb_t m_buffer[limb_count];
  585. };
  586. #ifdef BOOST_MSVC
  587. #pragma warning(pop)
  588. #endif
  589. } // namespace detail
  590. template <unsigned digits10, mpfr_allocation_type AllocationType>
  591. struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
  592. {
  593. mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
  594. mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
  595. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  596. mpfr_float_backend(mpfr_float_backend&& o) : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o)) {}
  597. #endif
  598. template <unsigned D, mpfr_allocation_type AT>
  599. mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename enable_if_c<D <= digits10>::type* = 0)
  600. : detail::mpfr_float_imp<digits10, AllocationType>()
  601. {
  602. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  603. }
  604. template <unsigned D, mpfr_allocation_type AT>
  605. explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename disable_if_c<D <= digits10>::type* = 0)
  606. : detail::mpfr_float_imp<digits10, AllocationType>()
  607. {
  608. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  609. }
  610. template <unsigned D>
  611. mpfr_float_backend(const gmp_float<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
  612. : detail::mpfr_float_imp<digits10, AllocationType>()
  613. {
  614. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  615. }
  616. template <unsigned D>
  617. mpfr_float_backend(const gmp_float<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
  618. : detail::mpfr_float_imp<digits10, AllocationType>()
  619. {
  620. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  621. }
  622. mpfr_float_backend(const gmp_int& val)
  623. : detail::mpfr_float_imp<digits10, AllocationType>()
  624. {
  625. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  626. }
  627. mpfr_float_backend(const gmp_rational& val)
  628. : detail::mpfr_float_imp<digits10, AllocationType>()
  629. {
  630. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  631. }
  632. mpfr_float_backend(const mpfr_t val)
  633. : detail::mpfr_float_imp<digits10, AllocationType>()
  634. {
  635. mpfr_set(this->m_data, val, GMP_RNDN);
  636. }
  637. mpfr_float_backend(const mpf_t val)
  638. : detail::mpfr_float_imp<digits10, AllocationType>()
  639. {
  640. mpfr_set_f(this->m_data, val, GMP_RNDN);
  641. }
  642. mpfr_float_backend(const mpz_t val)
  643. : detail::mpfr_float_imp<digits10, AllocationType>()
  644. {
  645. mpfr_set_z(this->m_data, val, GMP_RNDN);
  646. }
  647. mpfr_float_backend(const mpq_t val)
  648. : detail::mpfr_float_imp<digits10, AllocationType>()
  649. {
  650. mpfr_set_q(this->m_data, val, GMP_RNDN);
  651. }
  652. mpfr_float_backend& operator=(const mpfr_float_backend& o)
  653. {
  654. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
  655. return *this;
  656. }
  657. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  658. mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT
  659. {
  660. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
  661. return *this;
  662. }
  663. #endif
  664. template <class V>
  665. mpfr_float_backend& operator=(const V& v)
  666. {
  667. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
  668. return *this;
  669. }
  670. mpfr_float_backend& operator=(const mpfr_t val)
  671. {
  672. if(this->m_data[0]._mpfr_d == 0)
  673. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  674. mpfr_set(this->m_data, val, GMP_RNDN);
  675. return *this;
  676. }
  677. mpfr_float_backend& operator=(const mpf_t val)
  678. {
  679. if(this->m_data[0]._mpfr_d == 0)
  680. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  681. mpfr_set_f(this->m_data, val, GMP_RNDN);
  682. return *this;
  683. }
  684. mpfr_float_backend& operator=(const mpz_t val)
  685. {
  686. if(this->m_data[0]._mpfr_d == 0)
  687. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  688. mpfr_set_z(this->m_data, val, GMP_RNDN);
  689. return *this;
  690. }
  691. mpfr_float_backend& operator=(const mpq_t val)
  692. {
  693. if(this->m_data[0]._mpfr_d == 0)
  694. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  695. mpfr_set_q(this->m_data, val, GMP_RNDN);
  696. return *this;
  697. }
  698. // We don't change our precision here, this is a fixed precision type:
  699. template <unsigned D, mpfr_allocation_type AT>
  700. mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
  701. {
  702. if(this->m_data[0]._mpfr_d == 0)
  703. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  704. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  705. return *this;
  706. }
  707. template <unsigned D>
  708. mpfr_float_backend& operator=(const gmp_float<D>& val)
  709. {
  710. if(this->m_data[0]._mpfr_d == 0)
  711. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  712. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  713. return *this;
  714. }
  715. mpfr_float_backend& operator=(const gmp_int& val)
  716. {
  717. if(this->m_data[0]._mpfr_d == 0)
  718. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  719. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  720. return *this;
  721. }
  722. mpfr_float_backend& operator=(const gmp_rational& val)
  723. {
  724. if(this->m_data[0]._mpfr_d == 0)
  725. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  726. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  727. return *this;
  728. }
  729. };
  730. template <>
  731. struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
  732. {
  733. mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
  734. mpfr_float_backend(const mpfr_t val)
  735. : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val))
  736. {
  737. mpfr_set(this->m_data, val, GMP_RNDN);
  738. }
  739. mpfr_float_backend(const mpf_t val)
  740. : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val))
  741. {
  742. mpfr_set_f(this->m_data, val, GMP_RNDN);
  743. }
  744. mpfr_float_backend(const mpz_t val)
  745. : detail::mpfr_float_imp<0, allocate_dynamic>()
  746. {
  747. mpfr_set_z(this->m_data, val, GMP_RNDN);
  748. }
  749. mpfr_float_backend(const mpq_t val)
  750. : detail::mpfr_float_imp<0, allocate_dynamic>()
  751. {
  752. mpfr_set_q(this->m_data, val, GMP_RNDN);
  753. }
  754. mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
  755. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  756. mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o)) {}
  757. #endif
  758. mpfr_float_backend(const mpfr_float_backend& o, unsigned digits10)
  759. : detail::mpfr_float_imp<0, allocate_dynamic>(digits10)
  760. {
  761. *this = o;
  762. }
  763. template <unsigned D>
  764. mpfr_float_backend(const mpfr_float_backend<D>& val)
  765. : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val.data()))
  766. {
  767. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  768. }
  769. template <unsigned D>
  770. mpfr_float_backend(const gmp_float<D>& val)
  771. : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val.data()))
  772. {
  773. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  774. }
  775. mpfr_float_backend(const gmp_int& val)
  776. : detail::mpfr_float_imp<0, allocate_dynamic>()
  777. {
  778. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  779. }
  780. mpfr_float_backend(const gmp_rational& val)
  781. : detail::mpfr_float_imp<0, allocate_dynamic>()
  782. {
  783. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  784. }
  785. mpfr_float_backend& operator=(const mpfr_float_backend& o)
  786. {
  787. if(this->m_data[0]._mpfr_d == 0)
  788. mpfr_init2(this->m_data, mpfr_get_prec(o.data()));
  789. else
  790. mpfr_set_prec(this->m_data, mpfr_get_prec(o.data()));
  791. mpfr_set(this->m_data, o.data(), GMP_RNDN);
  792. return *this;
  793. }
  794. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  795. mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT
  796. {
  797. *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = static_cast<detail::mpfr_float_imp<0, allocate_dynamic> &&>(o);
  798. return *this;
  799. }
  800. #endif
  801. template <class V>
  802. mpfr_float_backend& operator=(const V& v)
  803. {
  804. *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
  805. return *this;
  806. }
  807. mpfr_float_backend& operator=(const mpfr_t val)
  808. {
  809. if(this->m_data[0]._mpfr_d == 0)
  810. mpfr_init2(this->m_data, mpfr_get_prec(val));
  811. else
  812. mpfr_set_prec(this->m_data, mpfr_get_prec(val));
  813. mpfr_set(this->m_data, val, GMP_RNDN);
  814. return *this;
  815. }
  816. mpfr_float_backend& operator=(const mpf_t val)
  817. {
  818. if(this->m_data[0]._mpfr_d == 0)
  819. mpfr_init2(this->m_data, mpf_get_prec(val));
  820. else
  821. mpfr_set_prec(this->m_data, mpf_get_prec(val));
  822. mpfr_set_f(this->m_data, val, GMP_RNDN);
  823. return *this;
  824. }
  825. mpfr_float_backend& operator=(const mpz_t val)
  826. {
  827. if(this->m_data[0]._mpfr_d == 0)
  828. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
  829. mpfr_set_z(this->m_data, val, GMP_RNDN);
  830. return *this;
  831. }
  832. mpfr_float_backend& operator=(const mpq_t val)
  833. {
  834. if(this->m_data[0]._mpfr_d == 0)
  835. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
  836. mpfr_set_q(this->m_data, val, GMP_RNDN);
  837. return *this;
  838. }
  839. template <unsigned D>
  840. mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
  841. {
  842. if(this->m_data[0]._mpfr_d == 0)
  843. mpfr_init2(this->m_data, mpfr_get_prec(val.data()));
  844. else
  845. mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
  846. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  847. return *this;
  848. }
  849. template <unsigned D>
  850. mpfr_float_backend& operator=(const gmp_float<D>& val)
  851. {
  852. if(this->m_data[0]._mpfr_d == 0)
  853. mpfr_init2(this->m_data, mpf_get_prec(val.data()));
  854. else
  855. mpfr_set_prec(this->m_data, mpf_get_prec(val.data()));
  856. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  857. return *this;
  858. }
  859. mpfr_float_backend& operator=(const gmp_int& val)
  860. {
  861. if(this->m_data[0]._mpfr_d == 0)
  862. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
  863. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  864. return *this;
  865. }
  866. mpfr_float_backend& operator=(const gmp_rational& val)
  867. {
  868. if(this->m_data[0]._mpfr_d == 0)
  869. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
  870. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  871. return *this;
  872. }
  873. static unsigned default_precision() BOOST_NOEXCEPT
  874. {
  875. return get_default_precision();
  876. }
  877. static void default_precision(unsigned v) BOOST_NOEXCEPT
  878. {
  879. get_default_precision() = v;
  880. }
  881. unsigned precision()const BOOST_NOEXCEPT
  882. {
  883. return multiprecision::detail::digits2_2_10(mpfr_get_prec(this->m_data));
  884. }
  885. void precision(unsigned digits10) BOOST_NOEXCEPT
  886. {
  887. mpfr_prec_round(this->m_data, multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
  888. }
  889. };
  890. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  891. inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
  892. {
  893. return a.compare(b) == 0;
  894. }
  895. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  896. inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
  897. {
  898. return a.compare(b) < 0;
  899. }
  900. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  901. inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
  902. {
  903. return a.compare(b) > 0;
  904. }
  905. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  906. inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  907. {
  908. mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
  909. }
  910. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  911. inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  912. {
  913. mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
  914. }
  915. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  916. inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  917. {
  918. if((void*)&o == (void*)&result)
  919. mpfr_sqr(result.data(), o.data(), GMP_RNDN);
  920. else
  921. mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
  922. }
  923. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  924. inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  925. {
  926. mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
  927. }
  928. template <unsigned digits10, mpfr_allocation_type AllocationType>
  929. inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  930. {
  931. mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
  932. }
  933. template <unsigned digits10, mpfr_allocation_type AllocationType>
  934. inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  935. {
  936. mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
  937. }
  938. template <unsigned digits10, mpfr_allocation_type AllocationType>
  939. inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  940. {
  941. mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
  942. }
  943. template <unsigned digits10, mpfr_allocation_type AllocationType>
  944. inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  945. {
  946. mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
  947. }
  948. template <unsigned digits10, mpfr_allocation_type AllocationType>
  949. inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
  950. {
  951. if(i > 0)
  952. mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
  953. else
  954. mpfr_sub_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
  955. }
  956. template <unsigned digits10, mpfr_allocation_type AllocationType>
  957. inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
  958. {
  959. if(i > 0)
  960. mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
  961. else
  962. mpfr_add_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
  963. }
  964. template <unsigned digits10, mpfr_allocation_type AllocationType>
  965. inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
  966. {
  967. mpfr_mul_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
  968. if(i < 0)
  969. mpfr_neg(result.data(), result.data(), GMP_RNDN);
  970. }
  971. template <unsigned digits10, mpfr_allocation_type AllocationType>
  972. inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
  973. {
  974. mpfr_div_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
  975. if(i < 0)
  976. mpfr_neg(result.data(), result.data(), GMP_RNDN);
  977. }
  978. //
  979. // Specialised 3 arg versions of the basic operators:
  980. //
  981. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
  982. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
  983. {
  984. mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
  985. }
  986. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  987. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  988. {
  989. mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
  990. }
  991. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  992. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  993. {
  994. if(y < 0)
  995. mpfr_sub_ui(a.data(), x.data(), -y, GMP_RNDN);
  996. else
  997. mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
  998. }
  999. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1000. inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1001. {
  1002. mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
  1003. }
  1004. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1005. inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1006. {
  1007. if(x < 0)
  1008. {
  1009. mpfr_ui_sub(a.data(), -x, y.data(), GMP_RNDN);
  1010. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1011. }
  1012. else
  1013. mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
  1014. }
  1015. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
  1016. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
  1017. {
  1018. mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
  1019. }
  1020. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1021. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1022. {
  1023. mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
  1024. }
  1025. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1026. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1027. {
  1028. if(y < 0)
  1029. mpfr_add_ui(a.data(), x.data(), -y, GMP_RNDN);
  1030. else
  1031. mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
  1032. }
  1033. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1034. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1035. {
  1036. mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
  1037. }
  1038. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1039. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1040. {
  1041. if(x < 0)
  1042. {
  1043. mpfr_add_ui(a.data(), y.data(), -x, GMP_RNDN);
  1044. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1045. }
  1046. else
  1047. mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
  1048. }
  1049. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
  1050. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
  1051. {
  1052. if((void*)&x == (void*)&y)
  1053. mpfr_sqr(a.data(), x.data(), GMP_RNDN);
  1054. else
  1055. mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
  1056. }
  1057. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1058. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1059. {
  1060. mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
  1061. }
  1062. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1063. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1064. {
  1065. if(y < 0)
  1066. {
  1067. mpfr_mul_ui(a.data(), x.data(), -y, GMP_RNDN);
  1068. a.negate();
  1069. }
  1070. else
  1071. mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
  1072. }
  1073. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1074. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1075. {
  1076. mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
  1077. }
  1078. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1079. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1080. {
  1081. if(x < 0)
  1082. {
  1083. mpfr_mul_ui(a.data(), y.data(), -x, GMP_RNDN);
  1084. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1085. }
  1086. else
  1087. mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
  1088. }
  1089. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
  1090. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
  1091. {
  1092. mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
  1093. }
  1094. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1095. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1096. {
  1097. mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
  1098. }
  1099. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1100. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1101. {
  1102. if(y < 0)
  1103. {
  1104. mpfr_div_ui(a.data(), x.data(), -y, GMP_RNDN);
  1105. a.negate();
  1106. }
  1107. else
  1108. mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
  1109. }
  1110. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1111. inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1112. {
  1113. mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
  1114. }
  1115. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1116. inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1117. {
  1118. if(x < 0)
  1119. {
  1120. mpfr_ui_div(a.data(), -x, y.data(), GMP_RNDN);
  1121. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1122. }
  1123. else
  1124. mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
  1125. }
  1126. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1127. inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
  1128. {
  1129. return 0 != mpfr_zero_p(val.data());
  1130. }
  1131. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1132. inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
  1133. {
  1134. return mpfr_sgn(val.data());
  1135. }
  1136. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1137. inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1138. {
  1139. if(mpfr_nan_p(val.data()))
  1140. {
  1141. BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1142. }
  1143. *result = mpfr_get_ui(val.data(), GMP_RNDZ);
  1144. }
  1145. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1146. inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1147. {
  1148. if(mpfr_nan_p(val.data()))
  1149. {
  1150. BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1151. }
  1152. *result = mpfr_get_si(val.data(), GMP_RNDZ);
  1153. }
  1154. #ifdef _MPFR_H_HAVE_INTMAX_T
  1155. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1156. inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1157. {
  1158. if(mpfr_nan_p(val.data()))
  1159. {
  1160. BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1161. }
  1162. *result = mpfr_get_uj(val.data(), GMP_RNDZ);
  1163. }
  1164. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1165. inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1166. {
  1167. if(mpfr_nan_p(val.data()))
  1168. {
  1169. BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1170. }
  1171. *result = mpfr_get_sj(val.data(), GMP_RNDZ);
  1172. }
  1173. #endif
  1174. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1175. inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
  1176. {
  1177. *result = mpfr_get_d(val.data(), GMP_RNDN);
  1178. }
  1179. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1180. inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
  1181. {
  1182. *result = mpfr_get_ld(val.data(), GMP_RNDN);
  1183. }
  1184. //
  1185. // Native non-member operations:
  1186. //
  1187. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1188. inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1189. {
  1190. mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
  1191. }
  1192. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1193. inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1194. {
  1195. mpfr_abs(result.data(), val.data(), GMP_RNDN);
  1196. }
  1197. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1198. inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1199. {
  1200. mpfr_abs(result.data(), val.data(), GMP_RNDN);
  1201. }
  1202. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1203. inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1204. {
  1205. mpfr_ceil(result.data(), val.data());
  1206. }
  1207. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1208. inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1209. {
  1210. mpfr_floor(result.data(), val.data());
  1211. }
  1212. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1213. inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1214. {
  1215. if(0 == mpfr_number_p(val.data()))
  1216. {
  1217. result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<mpfr_float_backend<Digits10, AllocateType> >(val), number<mpfr_float_backend<Digits10, AllocateType> >(val), boost::math::policies::policy<>()).backend();
  1218. return;
  1219. }
  1220. mpfr_trunc(result.data(), val.data());
  1221. }
  1222. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1223. inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
  1224. {
  1225. if(e > 0)
  1226. mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN);
  1227. else if(e < 0)
  1228. mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN);
  1229. else
  1230. result = val;
  1231. }
  1232. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1233. inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
  1234. {
  1235. long v;
  1236. mpfr_get_d_2exp(&v, val.data(), GMP_RNDN);
  1237. *e = v;
  1238. eval_ldexp(result, val, -v);
  1239. }
  1240. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1241. inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
  1242. {
  1243. mpfr_get_d_2exp(e, val.data(), GMP_RNDN);
  1244. return eval_ldexp(result, val, -*e);
  1245. }
  1246. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1247. inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) BOOST_NOEXCEPT
  1248. {
  1249. return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
  1250. }
  1251. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1252. inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
  1253. {
  1254. mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
  1255. }
  1256. #ifdef BOOST_MSVC
  1257. //
  1258. // The enable_if usage below doesn't work with msvc - but only when
  1259. // certain other enable_if usages are defined first. It's a capricious
  1260. // and rather annoying compiler bug in other words....
  1261. //
  1262. # define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10) &&
  1263. #else
  1264. #define BOOST_MP_ENABLE_IF_WORKAROUND
  1265. #endif
  1266. template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
  1267. inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type
  1268. eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
  1269. {
  1270. mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
  1271. }
  1272. template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
  1273. inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type
  1274. eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
  1275. {
  1276. mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
  1277. }
  1278. #undef BOOST_MP_ENABLE_IF_WORKAROUND
  1279. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1280. inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1281. {
  1282. mpfr_exp(result.data(), arg.data(), GMP_RNDN);
  1283. }
  1284. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1285. inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1286. {
  1287. mpfr_log(result.data(), arg.data(), GMP_RNDN);
  1288. }
  1289. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1290. inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1291. {
  1292. mpfr_log10(result.data(), arg.data(), GMP_RNDN);
  1293. }
  1294. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1295. inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1296. {
  1297. mpfr_sin(result.data(), arg.data(), GMP_RNDN);
  1298. }
  1299. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1300. inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1301. {
  1302. mpfr_cos(result.data(), arg.data(), GMP_RNDN);
  1303. }
  1304. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1305. inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1306. {
  1307. mpfr_tan(result.data(), arg.data(), GMP_RNDN);
  1308. }
  1309. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1310. inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1311. {
  1312. mpfr_asin(result.data(), arg.data(), GMP_RNDN);
  1313. }
  1314. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1315. inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1316. {
  1317. mpfr_acos(result.data(), arg.data(), GMP_RNDN);
  1318. }
  1319. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1320. inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1321. {
  1322. mpfr_atan(result.data(), arg.data(), GMP_RNDN);
  1323. }
  1324. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1325. inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
  1326. {
  1327. mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
  1328. }
  1329. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1330. inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1331. {
  1332. mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
  1333. }
  1334. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1335. inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1336. {
  1337. mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
  1338. }
  1339. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1340. inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1341. {
  1342. mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
  1343. }
  1344. } // namespace backends
  1345. #ifdef BOOST_NO_SFINAE_EXPR
  1346. namespace detail{
  1347. template<unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1348. struct is_explicitly_convertible<backends::mpfr_float_backend<D1, A1>, backends::mpfr_float_backend<D2, A2> > : public mpl::true_ {};
  1349. }
  1350. #endif
  1351. template<>
  1352. struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
  1353. using boost::multiprecision::backends::mpfr_float_backend;
  1354. typedef number<mpfr_float_backend<50> > mpfr_float_50;
  1355. typedef number<mpfr_float_backend<100> > mpfr_float_100;
  1356. typedef number<mpfr_float_backend<500> > mpfr_float_500;
  1357. typedef number<mpfr_float_backend<1000> > mpfr_float_1000;
  1358. typedef number<mpfr_float_backend<0> > mpfr_float;
  1359. typedef number<mpfr_float_backend<50, allocate_stack> > static_mpfr_float_50;
  1360. typedef number<mpfr_float_backend<100, allocate_stack> > static_mpfr_float_100;
  1361. } // namespace multiprecision
  1362. namespace math{
  1363. namespace tools{
  1364. template <>
  1365. inline int digits<boost::multiprecision::mpfr_float>()
  1366. {
  1367. return boost::multiprecision::backends::detail::get_default_precision();
  1368. }
  1369. template <>
  1370. inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
  1371. {
  1372. return boost::multiprecision::backends::detail::get_default_precision();
  1373. }
  1374. } // namespace tools
  1375. namespace constants{ namespace detail{
  1376. template <class T> struct constant_pi;
  1377. template <class T> struct constant_ln_two;
  1378. template <class T> struct constant_euler;
  1379. template <class T> struct constant_catalan;
  1380. namespace detail{
  1381. template <class T, int N>
  1382. struct mpfr_constant_initializer
  1383. {
  1384. static void force_instantiate()
  1385. {
  1386. init.force_instantiate();
  1387. }
  1388. private:
  1389. struct initializer
  1390. {
  1391. initializer()
  1392. {
  1393. T::get(mpl::int_<N>());
  1394. }
  1395. void force_instantiate()const{}
  1396. };
  1397. static const initializer init;
  1398. };
  1399. template <class T, int N>
  1400. typename mpfr_constant_initializer<T, N>::initializer const mpfr_constant_initializer<T, N>::init;
  1401. }
  1402. template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1403. struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  1404. {
  1405. typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
  1406. template<int N>
  1407. static inline const result_type& get(const mpl::int_<N>&)
  1408. {
  1409. detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
  1410. static result_type result;
  1411. static bool has_init = false;
  1412. if(!has_init)
  1413. {
  1414. mpfr_const_pi(result.backend().data(), GMP_RNDN);
  1415. has_init = true;
  1416. }
  1417. return result;
  1418. }
  1419. };
  1420. template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1421. struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  1422. {
  1423. typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
  1424. template<int N>
  1425. static inline const result_type& get(const mpl::int_<N>&)
  1426. {
  1427. detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
  1428. static result_type result;
  1429. static bool init = false;
  1430. if(!init)
  1431. {
  1432. mpfr_const_log2(result.backend().data(), GMP_RNDN);
  1433. init = true;
  1434. }
  1435. return result;
  1436. }
  1437. };
  1438. template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1439. struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  1440. {
  1441. typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
  1442. template<int N>
  1443. static inline const result_type& get(const mpl::int_<N>&)
  1444. {
  1445. detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
  1446. static result_type result;
  1447. static bool init = false;
  1448. if(!init)
  1449. {
  1450. mpfr_const_euler(result.backend().data(), GMP_RNDN);
  1451. init = true;
  1452. }
  1453. return result;
  1454. }
  1455. };
  1456. template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1457. struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  1458. {
  1459. typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
  1460. template<int N>
  1461. static inline const result_type& get(const mpl::int_<N>&)
  1462. {
  1463. detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
  1464. static result_type result;
  1465. static bool init = false;
  1466. if(!init)
  1467. {
  1468. mpfr_const_catalan(result.backend().data(), GMP_RNDN);
  1469. init = true;
  1470. }
  1471. return result;
  1472. }
  1473. };
  1474. }} // namespaces
  1475. }} // namespaces
  1476. namespace std{
  1477. //
  1478. // numeric_limits [partial] specializations for the types declared in this header:
  1479. //
  1480. template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1481. class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  1482. {
  1483. typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> number_type;
  1484. public:
  1485. BOOST_STATIC_CONSTEXPR bool is_specialized = true;
  1486. static number_type (min)()
  1487. {
  1488. initializer.do_nothing();
  1489. static std::pair<bool, number_type> value;
  1490. if(!value.first)
  1491. {
  1492. value.first = true;
  1493. value.second = 0.5;
  1494. mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin(), GMP_RNDN);
  1495. }
  1496. return value.second;
  1497. }
  1498. static number_type (max)()
  1499. {
  1500. initializer.do_nothing();
  1501. static std::pair<bool, number_type> value;
  1502. if(!value.first)
  1503. {
  1504. value.first = true;
  1505. value.second = 0.5;
  1506. mpfr_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax(), GMP_RNDN);
  1507. }
  1508. return value.second;
  1509. }
  1510. BOOST_STATIC_CONSTEXPR number_type lowest()
  1511. {
  1512. return -(max)();
  1513. }
  1514. BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
  1515. BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
  1516. // Is this really correct???
  1517. BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2;
  1518. BOOST_STATIC_CONSTEXPR bool is_signed = true;
  1519. BOOST_STATIC_CONSTEXPR bool is_integer = false;
  1520. BOOST_STATIC_CONSTEXPR bool is_exact = false;
  1521. BOOST_STATIC_CONSTEXPR int radix = 2;
  1522. static number_type epsilon()
  1523. {
  1524. initializer.do_nothing();
  1525. static std::pair<bool, number_type> value;
  1526. if(!value.first)
  1527. {
  1528. value.first = true;
  1529. value.second = 1;
  1530. mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
  1531. }
  1532. return value.second;
  1533. }
  1534. // What value should this be????
  1535. static number_type round_error()
  1536. {
  1537. // returns epsilon/2
  1538. initializer.do_nothing();
  1539. static std::pair<bool, number_type> value;
  1540. if(!value.first)
  1541. {
  1542. value.first = true;
  1543. value.second = 1;
  1544. mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), 1, GMP_RNDN);
  1545. }
  1546. return value.second;
  1547. }
  1548. BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
  1549. BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
  1550. BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
  1551. BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
  1552. BOOST_STATIC_CONSTEXPR bool has_infinity = true;
  1553. BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
  1554. BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
  1555. BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
  1556. BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
  1557. static number_type infinity()
  1558. {
  1559. // returns epsilon/2
  1560. initializer.do_nothing();
  1561. static std::pair<bool, number_type> value;
  1562. if(!value.first)
  1563. {
  1564. value.first = true;
  1565. value.second = 1;
  1566. mpfr_set_inf(value.second.backend().data(), 1);
  1567. }
  1568. return value.second;
  1569. }
  1570. static number_type quiet_NaN()
  1571. {
  1572. // returns epsilon/2
  1573. initializer.do_nothing();
  1574. static std::pair<bool, number_type> value;
  1575. if(!value.first)
  1576. {
  1577. value.first = true;
  1578. value.second = 1;
  1579. mpfr_set_nan(value.second.backend().data());
  1580. }
  1581. return value.second;
  1582. }
  1583. BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
  1584. {
  1585. return number_type(0);
  1586. }
  1587. BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
  1588. BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
  1589. BOOST_STATIC_CONSTEXPR bool is_bounded = true;
  1590. BOOST_STATIC_CONSTEXPR bool is_modulo = false;
  1591. BOOST_STATIC_CONSTEXPR bool traps = true;
  1592. BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
  1593. BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
  1594. private:
  1595. struct data_initializer
  1596. {
  1597. data_initializer()
  1598. {
  1599. std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::epsilon();
  1600. std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::round_error();
  1601. (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::min)();
  1602. (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::max)();
  1603. std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::infinity();
  1604. std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::quiet_NaN();
  1605. }
  1606. void do_nothing()const{}
  1607. };
  1608. static const data_initializer initializer;
  1609. };
  1610. template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1611. const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::initializer;
  1612. #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  1613. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1614. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
  1615. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1616. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
  1617. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1618. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
  1619. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1620. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
  1621. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1622. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
  1623. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1624. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
  1625. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1626. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
  1627. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1628. BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
  1629. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1630. BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
  1631. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1632. BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
  1633. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1634. BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
  1635. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1636. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
  1637. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1638. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
  1639. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1640. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
  1641. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1642. BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
  1643. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1644. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
  1645. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1646. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
  1647. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1648. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
  1649. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1650. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
  1651. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1652. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
  1653. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1654. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
  1655. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1656. BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
  1657. #endif
  1658. template<boost::multiprecision::expression_template_option ExpressionTemplates>
  1659. class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
  1660. {
  1661. typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> number_type;
  1662. public:
  1663. BOOST_STATIC_CONSTEXPR bool is_specialized = false;
  1664. static number_type (min)() { return number_type(0); }
  1665. static number_type (max)() { return number_type(0); }
  1666. static number_type lowest() { return number_type(0); }
  1667. BOOST_STATIC_CONSTEXPR int digits = 0;
  1668. BOOST_STATIC_CONSTEXPR int digits10 = 0;
  1669. BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
  1670. BOOST_STATIC_CONSTEXPR bool is_signed = false;
  1671. BOOST_STATIC_CONSTEXPR bool is_integer = false;
  1672. BOOST_STATIC_CONSTEXPR bool is_exact = false;
  1673. BOOST_STATIC_CONSTEXPR int radix = 0;
  1674. static number_type epsilon() { return number_type(0); }
  1675. static number_type round_error() { return number_type(0); }
  1676. BOOST_STATIC_CONSTEXPR int min_exponent = 0;
  1677. BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
  1678. BOOST_STATIC_CONSTEXPR int max_exponent = 0;
  1679. BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
  1680. BOOST_STATIC_CONSTEXPR bool has_infinity = false;
  1681. BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
  1682. BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
  1683. BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
  1684. BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
  1685. static number_type infinity() { return number_type(0); }
  1686. static number_type quiet_NaN() { return number_type(0); }
  1687. static number_type signaling_NaN() { return number_type(0); }
  1688. static number_type denorm_min() { return number_type(0); }
  1689. BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
  1690. BOOST_STATIC_CONSTEXPR bool is_bounded = false;
  1691. BOOST_STATIC_CONSTEXPR bool is_modulo = false;
  1692. BOOST_STATIC_CONSTEXPR bool traps = false;
  1693. BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
  1694. BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
  1695. };
  1696. #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  1697. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1698. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
  1699. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1700. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
  1701. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1702. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
  1703. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1704. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
  1705. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1706. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
  1707. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1708. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
  1709. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1710. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
  1711. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1712. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
  1713. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1714. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
  1715. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1716. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
  1717. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1718. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
  1719. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1720. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
  1721. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1722. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
  1723. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1724. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
  1725. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1726. BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
  1727. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1728. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
  1729. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1730. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
  1731. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1732. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
  1733. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1734. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
  1735. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1736. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
  1737. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1738. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
  1739. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1740. BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;
  1741. #endif
  1742. } // namespace std
  1743. #endif