mpfi.hpp 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509
  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_MPFI_HPP
  6. #define BOOST_MATH_BN_MPFI_HPP
  7. #include <boost/multiprecision/number.hpp>
  8. #include <boost/math/special_functions/fpclassify.hpp>
  9. #include <boost/cstdint.hpp>
  10. #include <boost/multiprecision/detail/big_lanczos.hpp>
  11. #include <boost/multiprecision/detail/digits.hpp>
  12. #include <boost/multiprecision/mpfr.hpp>
  13. #include <boost/math/constants/constants.hpp>
  14. #include <mpfi.h>
  15. #include <cmath>
  16. #include <algorithm>
  17. namespace boost{
  18. namespace multiprecision{
  19. namespace backends{
  20. template <unsigned digits10>
  21. struct mpfi_float_backend;
  22. } // namespace backends
  23. template <unsigned digits10>
  24. struct number_category<backends::mpfi_float_backend<digits10> > : public mpl::int_<number_kind_floating_point>{};
  25. struct interval_error : public std::runtime_error
  26. {
  27. interval_error(const std::string& s) : std::runtime_error(s) {}
  28. };
  29. namespace backends{
  30. namespace detail{
  31. inline int mpfi_sgn(mpfi_srcptr p)
  32. {
  33. if(mpfi_is_zero(p))
  34. return 0;
  35. if(mpfi_is_strictly_pos(p))
  36. return 1;
  37. if(mpfi_is_strictly_neg(p))
  38. return -1;
  39. BOOST_THROW_EXCEPTION(interval_error("Sign of interval is ambiguous."));
  40. }
  41. template <unsigned digits10>
  42. struct mpfi_float_imp;
  43. template <unsigned digits10>
  44. struct mpfi_float_imp
  45. {
  46. typedef mpl::list<long, long long> signed_types;
  47. typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
  48. typedef mpl::list<double, long double> float_types;
  49. typedef long exponent_type;
  50. mpfi_float_imp()
  51. {
  52. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  53. }
  54. mpfi_float_imp(unsigned prec)
  55. {
  56. mpfi_init2(m_data, prec);
  57. }
  58. mpfi_float_imp(const mpfi_float_imp& o)
  59. {
  60. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  61. if(o.m_data[0].left._mpfr_d)
  62. mpfi_set(m_data, o.m_data);
  63. }
  64. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  65. mpfi_float_imp(mpfi_float_imp&& o) BOOST_NOEXCEPT
  66. {
  67. m_data[0] = o.m_data[0];
  68. o.m_data[0].left._mpfr_d = 0;
  69. }
  70. #endif
  71. mpfi_float_imp& operator = (const mpfi_float_imp& o)
  72. {
  73. if(m_data[0].left._mpfr_d == 0)
  74. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  75. if(o.m_data[0].left._mpfr_d)
  76. mpfi_set(m_data, o.m_data);
  77. return *this;
  78. }
  79. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  80. mpfi_float_imp& operator = (mpfi_float_imp&& o) BOOST_NOEXCEPT
  81. {
  82. mpfi_swap(m_data, o.m_data);
  83. return *this;
  84. }
  85. #endif
  86. #ifdef _MPFR_H_HAVE_INTMAX_T
  87. mpfi_float_imp& operator = (unsigned long long i)
  88. {
  89. if(m_data[0].left._mpfr_d == 0)
  90. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  91. mpfr_set_uj(left_data(), i, GMP_RNDD);
  92. mpfr_set_uj(right_data(), i, GMP_RNDU);
  93. return *this;
  94. }
  95. mpfi_float_imp& operator = (long long i)
  96. {
  97. if(m_data[0].left._mpfr_d == 0)
  98. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  99. mpfr_set_sj(left_data(), i, GMP_RNDD);
  100. mpfr_set_sj(right_data(), i, GMP_RNDU);
  101. return *this;
  102. }
  103. #else
  104. mpfi_float_imp& operator = (unsigned long long i)
  105. {
  106. if(m_data[0].left._mpfr_d == 0)
  107. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  108. unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
  109. unsigned shift = 0;
  110. mpfi_t t;
  111. mpfi_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
  112. mpfi_set_ui(m_data, 0);
  113. while(i)
  114. {
  115. mpfi_set_ui(t, static_cast<unsigned>(i & mask));
  116. if(shift)
  117. mpfi_mul_2exp(t, t, shift);
  118. mpfi_add(m_data, m_data, t);
  119. shift += std::numeric_limits<unsigned>::digits;
  120. i >>= std::numeric_limits<unsigned>::digits;
  121. }
  122. mpfi_clear(t);
  123. return *this;
  124. }
  125. mpfi_float_imp& operator = (long long i)
  126. {
  127. BOOST_MP_USING_ABS
  128. if(m_data[0].left._mpfr_d == 0)
  129. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  130. bool neg = i < 0;
  131. *this = static_cast<unsigned long long>(abs(i));
  132. if(neg)
  133. mpfi_neg(m_data, m_data);
  134. return *this;
  135. }
  136. #endif
  137. mpfi_float_imp& operator = (unsigned long i)
  138. {
  139. if(m_data[0].left._mpfr_d == 0)
  140. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  141. mpfi_set_ui(m_data, i);
  142. return *this;
  143. }
  144. mpfi_float_imp& operator = (long i)
  145. {
  146. if(m_data[0].left._mpfr_d == 0)
  147. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  148. mpfi_set_si(m_data, i);
  149. return *this;
  150. }
  151. mpfi_float_imp& operator = (double d)
  152. {
  153. if(m_data[0].left._mpfr_d == 0)
  154. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  155. mpfi_set_d(m_data, d);
  156. return *this;
  157. }
  158. mpfi_float_imp& operator = (long double a)
  159. {
  160. if(m_data[0].left._mpfr_d == 0)
  161. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  162. mpfr_set_ld(left_data(), a, GMP_RNDD);
  163. mpfr_set_ld(right_data(), a, GMP_RNDU);
  164. return *this;
  165. }
  166. mpfi_float_imp& operator = (const char* s)
  167. {
  168. if(m_data[0].left._mpfr_d == 0)
  169. mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
  170. if(s && (*s == '{'))
  171. {
  172. mpfr_float_backend<digits10> a, b;
  173. std::string part;
  174. const char* p = ++s;
  175. while(*p && (*p != ',') && (*p != '}'))
  176. ++p;
  177. part.assign(s + 1, p);
  178. a = part.c_str();
  179. s = p;
  180. if(*p && (*p != '}'))
  181. {
  182. ++p;
  183. while(*p && (*p != ',') && (*p != '}'))
  184. ++p;
  185. part.assign(s + 1, p);
  186. }
  187. else
  188. part.erase();
  189. b = part.c_str();
  190. mpfi_interv_fr(m_data, a.data(), b.data());
  191. }
  192. else if(mpfi_set_str(m_data, s, 10) != 0)
  193. {
  194. BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
  195. }
  196. return *this;
  197. }
  198. void swap(mpfi_float_imp& o) BOOST_NOEXCEPT
  199. {
  200. mpfi_swap(m_data, o.m_data);
  201. }
  202. std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
  203. {
  204. BOOST_ASSERT(m_data[0].left._mpfr_d);
  205. mpfr_float_backend<digits10> a, b;
  206. mpfi_get_left(a.data(), m_data);
  207. mpfi_get_right(b.data(), m_data);
  208. if(a.compare(b) == 0)
  209. return a.str(digits, f);
  210. return "{" + a.str(digits, f) + "," + b.str(digits, f) + "}";
  211. }
  212. ~mpfi_float_imp() BOOST_NOEXCEPT
  213. {
  214. if(m_data[0].left._mpfr_d)
  215. mpfi_clear(m_data);
  216. }
  217. void negate() BOOST_NOEXCEPT
  218. {
  219. BOOST_ASSERT(m_data[0].left._mpfr_d);
  220. mpfi_neg(m_data, m_data);
  221. }
  222. int compare(const mpfi_float_imp& o)const BOOST_NOEXCEPT
  223. {
  224. BOOST_ASSERT(m_data[0].left._mpfr_d && o.m_data[0].left._mpfr_d);
  225. if(mpfr_cmp(right_data(), o.left_data()) < 0)
  226. return -1;
  227. if(mpfr_cmp(left_data(), o.right_data()) > 0)
  228. return 1;
  229. if((mpfr_cmp(left_data(), o.left_data()) == 0) && (mpfr_cmp(right_data(), o.right_data()) == 0))
  230. return 0;
  231. BOOST_THROW_EXCEPTION(interval_error("Ambiguous comparison between two values."));
  232. return 0;
  233. }
  234. template <class V>
  235. int compare(V v)const BOOST_NOEXCEPT
  236. {
  237. mpfi_float_imp d;
  238. d = v;
  239. return compare(d);
  240. }
  241. mpfi_t& data() BOOST_NOEXCEPT
  242. {
  243. BOOST_ASSERT(m_data[0].left._mpfr_d);
  244. return m_data;
  245. }
  246. const mpfi_t& data()const BOOST_NOEXCEPT
  247. {
  248. BOOST_ASSERT(m_data[0].left._mpfr_d);
  249. return m_data;
  250. }
  251. mpfr_ptr left_data() BOOST_NOEXCEPT
  252. {
  253. BOOST_ASSERT(m_data[0].left._mpfr_d);
  254. return &(m_data[0].left);
  255. }
  256. mpfr_srcptr left_data()const BOOST_NOEXCEPT
  257. {
  258. BOOST_ASSERT(m_data[0].left._mpfr_d);
  259. return &(m_data[0].left);
  260. }
  261. mpfr_ptr right_data() BOOST_NOEXCEPT
  262. {
  263. BOOST_ASSERT(m_data[0].left._mpfr_d);
  264. return &(m_data[0].right);
  265. }
  266. mpfr_srcptr right_data()const BOOST_NOEXCEPT
  267. {
  268. BOOST_ASSERT(m_data[0].left._mpfr_d);
  269. return &(m_data[0].right);
  270. }
  271. protected:
  272. mpfi_t m_data;
  273. static unsigned& get_default_precision() BOOST_NOEXCEPT
  274. {
  275. static unsigned val = 50;
  276. return val;
  277. }
  278. };
  279. } // namespace detail
  280. template <unsigned digits10>
  281. struct mpfi_float_backend : public detail::mpfi_float_imp<digits10>
  282. {
  283. mpfi_float_backend() : detail::mpfi_float_imp<digits10>() {}
  284. mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<digits10>(o) {}
  285. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  286. mpfi_float_backend(mpfi_float_backend&& o) : detail::mpfi_float_imp<digits10>(static_cast<detail::mpfi_float_imp<digits10>&&>(o)) {}
  287. #endif
  288. template <unsigned D>
  289. mpfi_float_backend(const mpfi_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
  290. : detail::mpfi_float_imp<digits10>()
  291. {
  292. mpfi_set(this->m_data, val.data());
  293. }
  294. template <unsigned D>
  295. explicit mpfi_float_backend(const mpfi_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
  296. : detail::mpfi_float_imp<digits10>()
  297. {
  298. mpfi_set(this->m_data, val.data());
  299. }
  300. mpfi_float_backend(const mpfi_t val)
  301. : detail::mpfi_float_imp<digits10>()
  302. {
  303. mpfi_set(this->m_data, val);
  304. }
  305. mpfi_float_backend& operator=(const mpfi_float_backend& o)
  306. {
  307. *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10> const&>(o);
  308. return *this;
  309. }
  310. template <unsigned D>
  311. mpfi_float_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
  312. : detail::mpfi_float_imp<digits10>()
  313. {
  314. mpfi_set_fr(this->m_data, val.data());
  315. }
  316. template <unsigned D>
  317. mpfi_float_backend& operator=(const mpfr_float_backend<D>& val)
  318. {
  319. mpfi_set_fr(this->m_data, val.data());
  320. return *this;
  321. }
  322. template <unsigned D>
  323. explicit mpfi_float_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
  324. : detail::mpfi_float_imp<digits10>()
  325. {
  326. mpfi_set_fr(this->m_data, val.data());
  327. }
  328. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  329. mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
  330. {
  331. *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10>&&>(o);
  332. return *this;
  333. }
  334. #endif
  335. template <class V>
  336. mpfi_float_backend& operator=(const V& v)
  337. {
  338. *static_cast<detail::mpfi_float_imp<digits10>*>(this) = v;
  339. return *this;
  340. }
  341. mpfi_float_backend& operator=(const mpfi_t val)
  342. {
  343. mpfi_set(this->m_data, val);
  344. return *this;
  345. }
  346. // We don't change our precision here, this is a fixed precision type:
  347. template <unsigned D>
  348. mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
  349. {
  350. mpfi_set(this->m_data, val.data());
  351. return *this;
  352. }
  353. };
  354. template <>
  355. struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0>
  356. {
  357. mpfi_float_backend() : detail::mpfi_float_imp<0>() {}
  358. mpfi_float_backend(const mpfi_t val)
  359. : detail::mpfi_float_imp<0>(mpfi_get_prec(val))
  360. {
  361. mpfi_set(this->m_data, val);
  362. }
  363. mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<0>(o) {}
  364. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  365. mpfi_float_backend(mpfi_float_backend&& o) BOOST_NOEXCEPT : detail::mpfi_float_imp<0>(static_cast<detail::mpfi_float_imp<0>&&>(o)) {}
  366. #endif
  367. mpfi_float_backend(const mpfi_float_backend& o, unsigned digits10)
  368. : detail::mpfi_float_imp<0>(digits10)
  369. {
  370. *this = o;
  371. }
  372. template <unsigned D>
  373. mpfi_float_backend(const mpfi_float_backend<D>& val)
  374. : detail::mpfi_float_imp<0>(mpfi_get_prec(val.data()))
  375. {
  376. mpfi_set(this->m_data, val.data());
  377. }
  378. mpfi_float_backend& operator=(const mpfi_float_backend& o)
  379. {
  380. mpfi_set_prec(this->m_data, mpfi_get_prec(o.data()));
  381. mpfi_set(this->m_data, o.data());
  382. return *this;
  383. }
  384. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  385. mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
  386. {
  387. *static_cast<detail::mpfi_float_imp<0>*>(this) = static_cast<detail::mpfi_float_imp<0> &&>(o);
  388. return *this;
  389. }
  390. #endif
  391. template <class V>
  392. mpfi_float_backend& operator=(const V& v)
  393. {
  394. *static_cast<detail::mpfi_float_imp<0>*>(this) = v;
  395. return *this;
  396. }
  397. mpfi_float_backend& operator=(const mpfi_t val)
  398. {
  399. mpfi_set_prec(this->m_data, mpfi_get_prec(val));
  400. mpfi_set(this->m_data, val);
  401. return *this;
  402. }
  403. template <unsigned D>
  404. mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
  405. {
  406. mpfi_set_prec(this->m_data, mpfi_get_prec(val.data()));
  407. mpfi_set(this->m_data, val.data());
  408. return *this;
  409. }
  410. static unsigned default_precision() BOOST_NOEXCEPT
  411. {
  412. return get_default_precision();
  413. }
  414. static void default_precision(unsigned v) BOOST_NOEXCEPT
  415. {
  416. get_default_precision() = v;
  417. }
  418. unsigned precision()const BOOST_NOEXCEPT
  419. {
  420. return multiprecision::detail::digits2_2_10(mpfi_get_prec(this->m_data));
  421. }
  422. void precision(unsigned digits10) BOOST_NOEXCEPT
  423. {
  424. mpfi_set_prec(this->m_data, multiprecision::detail::digits2_2_10((digits10)));
  425. }
  426. };
  427. template <unsigned digits10, class T>
  428. inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
  429. {
  430. return a.compare(b) == 0;
  431. }
  432. template <unsigned digits10, class T>
  433. inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
  434. {
  435. return a.compare(b) < 0;
  436. }
  437. template <unsigned digits10, class T>
  438. inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
  439. {
  440. return a.compare(b) > 0;
  441. }
  442. template <unsigned D1, unsigned D2>
  443. inline void eval_add(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
  444. {
  445. mpfi_add(result.data(), result.data(), o.data());
  446. }
  447. template <unsigned D1, unsigned D2>
  448. inline void eval_subtract(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
  449. {
  450. mpfi_sub(result.data(), result.data(), o.data());
  451. }
  452. template <unsigned D1, unsigned D2>
  453. inline void eval_multiply(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
  454. {
  455. if((void*)&result == (void*)&o)
  456. mpfi_sqr(result.data(), o.data());
  457. else
  458. mpfi_mul(result.data(), result.data(), o.data());
  459. }
  460. template <unsigned D1, unsigned D2>
  461. inline void eval_divide(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
  462. {
  463. mpfi_div(result.data(), result.data(), o.data());
  464. }
  465. template <unsigned digits10>
  466. inline void eval_add(mpfi_float_backend<digits10>& result, unsigned long i)
  467. {
  468. mpfi_add_ui(result.data(), result.data(), i);
  469. }
  470. template <unsigned digits10>
  471. inline void eval_subtract(mpfi_float_backend<digits10>& result, unsigned long i)
  472. {
  473. mpfi_sub_ui(result.data(), result.data(), i);
  474. }
  475. template <unsigned digits10>
  476. inline void eval_multiply(mpfi_float_backend<digits10>& result, unsigned long i)
  477. {
  478. mpfi_mul_ui(result.data(), result.data(), i);
  479. }
  480. template <unsigned digits10>
  481. inline void eval_divide(mpfi_float_backend<digits10>& result, unsigned long i)
  482. {
  483. mpfi_div_ui(result.data(), result.data(), i);
  484. }
  485. template <unsigned digits10>
  486. inline void eval_add(mpfi_float_backend<digits10>& result, long i)
  487. {
  488. if(i > 0)
  489. mpfi_add_ui(result.data(), result.data(), i);
  490. else
  491. mpfi_sub_ui(result.data(), result.data(), std::abs(i));
  492. }
  493. template <unsigned digits10>
  494. inline void eval_subtract(mpfi_float_backend<digits10>& result, long i)
  495. {
  496. if(i > 0)
  497. mpfi_sub_ui(result.data(), result.data(), i);
  498. else
  499. mpfi_add_ui(result.data(), result.data(), std::abs(i));
  500. }
  501. template <unsigned digits10>
  502. inline void eval_multiply(mpfi_float_backend<digits10>& result, long i)
  503. {
  504. mpfi_mul_ui(result.data(), result.data(), std::abs(i));
  505. if(i < 0)
  506. mpfi_neg(result.data(), result.data());
  507. }
  508. template <unsigned digits10>
  509. inline void eval_divide(mpfi_float_backend<digits10>& result, long i)
  510. {
  511. mpfi_div_ui(result.data(), result.data(), std::abs(i));
  512. if(i < 0)
  513. mpfi_neg(result.data(), result.data());
  514. }
  515. //
  516. // Specialised 3 arg versions of the basic operators:
  517. //
  518. template <unsigned D1, unsigned D2, unsigned D3>
  519. inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
  520. {
  521. mpfi_add(a.data(), x.data(), y.data());
  522. }
  523. template <unsigned D1, unsigned D2>
  524. inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
  525. {
  526. mpfi_add_ui(a.data(), x.data(), y);
  527. }
  528. template <unsigned D1, unsigned D2>
  529. inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
  530. {
  531. if(y < 0)
  532. mpfi_sub_ui(a.data(), x.data(), -y);
  533. else
  534. mpfi_add_ui(a.data(), x.data(), y);
  535. }
  536. template <unsigned D1, unsigned D2>
  537. inline void eval_add(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
  538. {
  539. mpfi_add_ui(a.data(), y.data(), x);
  540. }
  541. template <unsigned D1, unsigned D2>
  542. inline void eval_add(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
  543. {
  544. if(x < 0)
  545. {
  546. mpfi_ui_sub(a.data(), -x, y.data());
  547. mpfi_neg(a.data(), a.data());
  548. }
  549. else
  550. mpfi_add_ui(a.data(), y.data(), x);
  551. }
  552. template <unsigned D1, unsigned D2, unsigned D3>
  553. inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
  554. {
  555. mpfi_sub(a.data(), x.data(), y.data());
  556. }
  557. template <unsigned D1, unsigned D2>
  558. inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
  559. {
  560. mpfi_sub_ui(a.data(), x.data(), y);
  561. }
  562. template <unsigned D1, unsigned D2>
  563. inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
  564. {
  565. if(y < 0)
  566. mpfi_add_ui(a.data(), x.data(), -y);
  567. else
  568. mpfi_sub_ui(a.data(), x.data(), y);
  569. }
  570. template <unsigned D1, unsigned D2>
  571. inline void eval_subtract(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
  572. {
  573. mpfi_ui_sub(a.data(), x, y.data());
  574. }
  575. template <unsigned D1, unsigned D2>
  576. inline void eval_subtract(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
  577. {
  578. if(x < 0)
  579. {
  580. mpfi_add_ui(a.data(), y.data(), -x);
  581. mpfi_neg(a.data(), a.data());
  582. }
  583. else
  584. mpfi_ui_sub(a.data(), x, y.data());
  585. }
  586. template <unsigned D1, unsigned D2, unsigned D3>
  587. inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
  588. {
  589. if((void*)&x == (void*)&y)
  590. mpfi_sqr(a.data(), x.data());
  591. else
  592. mpfi_mul(a.data(), x.data(), y.data());
  593. }
  594. template <unsigned D1, unsigned D2>
  595. inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
  596. {
  597. mpfi_mul_ui(a.data(), x.data(), y);
  598. }
  599. template <unsigned D1, unsigned D2>
  600. inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
  601. {
  602. if(y < 0)
  603. {
  604. mpfi_mul_ui(a.data(), x.data(), -y);
  605. a.negate();
  606. }
  607. else
  608. mpfi_mul_ui(a.data(), x.data(), y);
  609. }
  610. template <unsigned D1, unsigned D2>
  611. inline void eval_multiply(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
  612. {
  613. mpfi_mul_ui(a.data(), y.data(), x);
  614. }
  615. template <unsigned D1, unsigned D2>
  616. inline void eval_multiply(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
  617. {
  618. if(x < 0)
  619. {
  620. mpfi_mul_ui(a.data(), y.data(), -x);
  621. mpfi_neg(a.data(), a.data());
  622. }
  623. else
  624. mpfi_mul_ui(a.data(), y.data(), x);
  625. }
  626. template <unsigned D1, unsigned D2, unsigned D3>
  627. inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
  628. {
  629. mpfi_div(a.data(), x.data(), y.data());
  630. }
  631. template <unsigned D1, unsigned D2>
  632. inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
  633. {
  634. mpfi_div_ui(a.data(), x.data(), y);
  635. }
  636. template <unsigned D1, unsigned D2>
  637. inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
  638. {
  639. if(y < 0)
  640. {
  641. mpfi_div_ui(a.data(), x.data(), -y);
  642. a.negate();
  643. }
  644. else
  645. mpfi_div_ui(a.data(), x.data(), y);
  646. }
  647. template <unsigned D1, unsigned D2>
  648. inline void eval_divide(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
  649. {
  650. mpfi_ui_div(a.data(), x, y.data());
  651. }
  652. template <unsigned D1, unsigned D2>
  653. inline void eval_divide(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
  654. {
  655. if(x < 0)
  656. {
  657. mpfi_ui_div(a.data(), -x, y.data());
  658. mpfi_neg(a.data(), a.data());
  659. }
  660. else
  661. mpfi_ui_div(a.data(), x, y.data());
  662. }
  663. template <unsigned digits10>
  664. inline bool eval_is_zero(const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
  665. {
  666. return 0 != mpfi_is_zero(val.data());
  667. }
  668. template <unsigned digits10>
  669. inline int eval_get_sign(const mpfi_float_backend<digits10>& val)
  670. {
  671. return detail::mpfi_sgn(val.data());
  672. }
  673. template <unsigned digits10>
  674. inline void eval_convert_to(unsigned long* result, const mpfi_float_backend<digits10>& val)
  675. {
  676. mpfr_float_backend<digits10> t;
  677. mpfi_mid(t.data(), val.data());
  678. eval_convert_to(result, t);
  679. }
  680. template <unsigned digits10>
  681. inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& val)
  682. {
  683. mpfr_float_backend<digits10> t;
  684. mpfi_mid(t.data(), val.data());
  685. eval_convert_to(result, t);
  686. }
  687. #ifdef _MPFR_H_HAVE_INTMAX_T
  688. template <unsigned digits10>
  689. inline void eval_convert_to(unsigned long long* result, const mpfi_float_backend<digits10>& val)
  690. {
  691. mpfr_float_backend<digits10> t;
  692. mpfi_mid(t.data(), val.data());
  693. eval_convert_to(result, t);
  694. }
  695. template <unsigned digits10>
  696. inline void eval_convert_to(long long* result, const mpfi_float_backend<digits10>& val)
  697. {
  698. mpfr_float_backend<digits10> t;
  699. mpfi_mid(t.data(), val.data());
  700. eval_convert_to(result, t);
  701. }
  702. #endif
  703. template <unsigned digits10>
  704. inline void eval_convert_to(double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
  705. {
  706. *result = mpfi_get_d(val.data());
  707. }
  708. template <unsigned digits10>
  709. inline void eval_convert_to(long double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
  710. {
  711. mpfr_float_backend<digits10> t;
  712. mpfi_mid(t.data(), val.data());
  713. eval_convert_to(result, t);
  714. }
  715. template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
  716. inline void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
  717. {
  718. mpfi_interv_fr(result.data(), a.data(), b.data());
  719. }
  720. template <unsigned Digits10, class V>
  721. inline typename enable_if_c<is_convertible<V, number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> >::value >::type
  722. assign_components(mpfi_float_backend<Digits10>& result, const V& a, const V& b)
  723. {
  724. number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> x(a), y(b);
  725. assign_components(result, x.backend(), y.backend());
  726. }
  727. //
  728. // Native non-member operations:
  729. //
  730. template <unsigned Digits10>
  731. inline void eval_sqrt(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
  732. {
  733. mpfi_sqrt(result.data(), val.data());
  734. }
  735. template <unsigned Digits10>
  736. inline void eval_abs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
  737. {
  738. mpfi_abs(result.data(), val.data());
  739. }
  740. template <unsigned Digits10>
  741. inline void eval_fabs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
  742. {
  743. mpfi_abs(result.data(), val.data());
  744. }
  745. template <unsigned Digits10>
  746. inline void eval_ceil(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
  747. {
  748. mpfr_float_backend<Digits10> a, b;
  749. mpfr_set(a.data(), val.left_data(), GMP_RNDN);
  750. mpfr_set(b.data(), val.right_data(), GMP_RNDN);
  751. eval_ceil(a, a);
  752. eval_ceil(b, b);
  753. if(a.compare(b) != 0)
  754. {
  755. BOOST_THROW_EXCEPTION(interval_error("Attempt to take the ceil of a value that straddles an integer boundary."));
  756. }
  757. mpfi_set_fr(result.data(), a.data());
  758. }
  759. template <unsigned Digits10>
  760. inline void eval_floor(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
  761. {
  762. mpfr_float_backend<Digits10> a, b;
  763. mpfr_set(a.data(), val.left_data(), GMP_RNDN);
  764. mpfr_set(b.data(), val.right_data(), GMP_RNDN);
  765. eval_floor(a, a);
  766. eval_floor(b, b);
  767. if(a.compare(b) != 0)
  768. {
  769. BOOST_THROW_EXCEPTION(interval_error("Attempt to take the floor of a value that straddles an integer boundary."));
  770. }
  771. mpfi_set_fr(result.data(), a.data());
  772. }
  773. template <unsigned Digits10>
  774. inline void eval_ldexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long e)
  775. {
  776. if(e > 0)
  777. mpfi_mul_2exp(result.data(), val.data(), e);
  778. else if(e < 0)
  779. mpfi_div_2exp(result.data(), val.data(), -e);
  780. else
  781. result = val;
  782. }
  783. template <unsigned Digits10>
  784. inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, int* e)
  785. {
  786. mpfr_float_backend<Digits10> t, rt;
  787. mpfi_mid(t.data(), val.data());
  788. eval_frexp(rt, t, e);
  789. eval_ldexp(result, val, -*e);
  790. }
  791. template <unsigned Digits10>
  792. inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long* e)
  793. {
  794. mpfr_float_backend<Digits10> t, rt;
  795. mpfi_mid(t.data(), val.data());
  796. eval_frexp(rt, t, e);
  797. eval_ldexp(result, val, -*e);
  798. }
  799. template <unsigned Digits10>
  800. inline int eval_fpclassify(const mpfi_float_backend<Digits10>& val) BOOST_NOEXCEPT
  801. {
  802. return mpfi_inf_p(val.data()) ? FP_INFINITE : mpfi_nan_p(val.data()) ? FP_NAN : mpfi_is_zero(val.data()) ? FP_ZERO : FP_NORMAL;
  803. }
  804. template <unsigned Digits10>
  805. inline void eval_pow(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& b, const mpfi_float_backend<Digits10>& e)
  806. {
  807. typedef typename boost::multiprecision::detail::canonical<unsigned, mpfi_float_backend<Digits10> >::type ui_type;
  808. using default_ops::eval_get_sign;
  809. int s = eval_get_sign(b);
  810. if(s == 0)
  811. {
  812. if(eval_get_sign(e) == 0)
  813. {
  814. result = ui_type(1);
  815. }
  816. else
  817. {
  818. result = ui_type(0);
  819. }
  820. return;
  821. }
  822. if(s < 0)
  823. {
  824. if(eval_get_sign(e) < 0)
  825. {
  826. mpfi_float_backend<Digits10> t1, t2;
  827. t1 = e;
  828. t1.negate();
  829. eval_pow(t2, b, t1);
  830. t1 = ui_type(1);
  831. eval_divide(result, t1, t2);
  832. return;
  833. }
  834. typename boost::multiprecision::detail::canonical<boost::uintmax_t, mpfi_float_backend<Digits10> >::type an;
  835. try
  836. {
  837. using default_ops::eval_convert_to;
  838. eval_convert_to(&an, e);
  839. if(e.compare(an) == 0)
  840. {
  841. mpfi_float_backend<Digits10> pb(b);
  842. pb.negate();
  843. eval_pow(result, pb, e);
  844. if(an & 1u)
  845. result.negate();
  846. return;
  847. }
  848. }
  849. catch(const std::exception&)
  850. {
  851. // conversion failed, just fall through, value is not an integer.
  852. }
  853. result = std::numeric_limits<number<mpfi_float_backend<Digits10>, et_on> >::quiet_NaN().backend();
  854. return;
  855. }
  856. mpfi_log(result.data(), b.data());
  857. mpfi_mul(result.data(), result.data(), e.data());
  858. mpfi_exp(result.data(), result.data());
  859. }
  860. template <unsigned Digits10>
  861. inline void eval_exp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  862. {
  863. mpfi_exp(result.data(), arg.data());
  864. }
  865. template <unsigned Digits10>
  866. inline void eval_log(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  867. {
  868. mpfi_log(result.data(), arg.data());
  869. }
  870. template <unsigned Digits10>
  871. inline void eval_log10(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  872. {
  873. mpfi_log10(result.data(), arg.data());
  874. }
  875. template <unsigned Digits10>
  876. inline void eval_sin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  877. {
  878. mpfi_sin(result.data(), arg.data());
  879. }
  880. template <unsigned Digits10>
  881. inline void eval_cos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  882. {
  883. mpfi_cos(result.data(), arg.data());
  884. }
  885. template <unsigned Digits10>
  886. inline void eval_tan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  887. {
  888. mpfi_tan(result.data(), arg.data());
  889. }
  890. template <unsigned Digits10>
  891. inline void eval_asin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  892. {
  893. mpfi_asin(result.data(), arg.data());
  894. }
  895. template <unsigned Digits10>
  896. inline void eval_acos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  897. {
  898. mpfi_acos(result.data(), arg.data());
  899. }
  900. template <unsigned Digits10>
  901. inline void eval_atan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  902. {
  903. mpfi_atan(result.data(), arg.data());
  904. }
  905. template <unsigned Digits10>
  906. inline void eval_atan2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg1, const mpfi_float_backend<Digits10>& arg2)
  907. {
  908. mpfi_atan2(result.data(), arg1.data(), arg2.data());
  909. }
  910. template <unsigned Digits10>
  911. inline void eval_sinh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  912. {
  913. mpfi_sinh(result.data(), arg.data());
  914. }
  915. template <unsigned Digits10>
  916. inline void eval_cosh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  917. {
  918. mpfi_cosh(result.data(), arg.data());
  919. }
  920. template <unsigned Digits10>
  921. inline void eval_tanh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
  922. {
  923. mpfi_tanh(result.data(), arg.data());
  924. }
  925. } // namespace backends
  926. #ifdef BOOST_NO_SFINAE_EXPR
  927. namespace detail{
  928. template<unsigned D1, unsigned D2>
  929. struct is_explicitly_convertible<backends::mpfi_float_backend<D1>, backends::mpfi_float_backend<D2> > : public mpl::true_ {};
  930. }
  931. #endif
  932. template<>
  933. struct number_category<detail::canonical<mpfi_t, backends::mpfi_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
  934. template <unsigned Digits10>
  935. struct is_interval_number<backends::mpfi_float_backend<Digits10> > : public mpl::true_ {};
  936. using boost::multiprecision::backends::mpfi_float_backend;
  937. typedef number<mpfi_float_backend<50> > mpfi_float_50;
  938. typedef number<mpfi_float_backend<100> > mpfi_float_100;
  939. typedef number<mpfi_float_backend<500> > mpfi_float_500;
  940. typedef number<mpfi_float_backend<1000> > mpfi_float_1000;
  941. typedef number<mpfi_float_backend<0> > mpfi_float;
  942. //
  943. // Special interval specific functions:
  944. //
  945. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  946. inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> lower(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
  947. {
  948. number<mpfr_float_backend<Digits10> > result;
  949. mpfr_set(result.backend().data(), val.backend().left_data(), GMP_RNDN);
  950. return result;
  951. }
  952. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  953. inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> upper(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
  954. {
  955. number<mpfr_float_backend<Digits10> > result;
  956. mpfr_set(result.backend().data(), val.backend().right_data(), GMP_RNDN);
  957. return result;
  958. }
  959. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  960. inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> median(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
  961. {
  962. number<mpfr_float_backend<Digits10> > result;
  963. mpfi_mid(result.backend().data(), val.backend().data());
  964. return result;
  965. }
  966. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  967. inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> width(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
  968. {
  969. number<mpfr_float_backend<Digits10> > result;
  970. mpfi_diam_abs(result.backend().data(), val.backend().data());
  971. return result;
  972. }
  973. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  974. inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> intersect(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
  975. {
  976. number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
  977. mpfi_intersect(result.backend().data(), a.backend().data(), b.backend().data());
  978. return result;
  979. }
  980. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  981. inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> hull(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
  982. {
  983. number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
  984. mpfi_union(result.backend().data(), a.backend().data(), b.backend().data());
  985. return result;
  986. }
  987. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  988. inline bool overlap(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
  989. {
  990. return (lower(a) <= lower(b) && lower(b) <= upper(a)) ||
  991. (lower(b) <= lower(a) && lower(a) <= upper(b));
  992. }
  993. template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
  994. inline bool in(const number<mpfr_float_backend<Digits10>, ExpressionTemplates1>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates2>& b)
  995. {
  996. return mpfi_is_inside_fr(a.backend().data(), b.backend().data()) != 0;
  997. }
  998. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  999. inline bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
  1000. {
  1001. return mpfi_has_zero(a.backend().data()) != 0;
  1002. }
  1003. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  1004. inline bool subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
  1005. {
  1006. return mpfi_is_inside(a.backend().data(), b.backend().data()) != 0;
  1007. }
  1008. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  1009. inline bool proper_subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
  1010. {
  1011. return mpfi_is_strictly_inside(a.backend().data(), b.backend().data()) != 0;
  1012. }
  1013. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  1014. inline bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
  1015. {
  1016. return mpfi_is_empty(a.backend().data()) != 0;
  1017. }
  1018. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  1019. inline bool singleton(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
  1020. {
  1021. return mpfr_cmp(a.backend().left_data(), a.backend().right_data()) == 0;
  1022. }
  1023. template <unsigned Digits10, expression_template_option ExpressionTemplates>
  1024. struct component_type<number<mpfi_float_backend<Digits10>, ExpressionTemplates> >
  1025. {
  1026. typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
  1027. };
  1028. } // namespace multiprecision
  1029. namespace math{
  1030. namespace tools{
  1031. template <>
  1032. inline int digits<boost::multiprecision::mpfi_float>()
  1033. {
  1034. return boost::multiprecision::backends::detail::get_default_precision();
  1035. }
  1036. template <>
  1037. inline int digits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
  1038. {
  1039. return boost::multiprecision::backends::detail::get_default_precision();
  1040. }
  1041. } // namespace tools
  1042. namespace constants{ namespace detail{
  1043. template <class T> struct constant_pi;
  1044. template <class T> struct constant_ln_two;
  1045. template <class T> struct constant_euler;
  1046. template <class T> struct constant_catalan;
  1047. //
  1048. // Initializer: ensure all our constants are initialized prior to the first call of main:
  1049. //
  1050. template <class T>
  1051. struct mpfi_initializer
  1052. {
  1053. struct init
  1054. {
  1055. init()
  1056. {
  1057. boost::math::constants::pi<T>();
  1058. boost::math::constants::ln_two<T>();
  1059. boost::math::constants::euler<T>();
  1060. boost::math::constants::catalan<T>();
  1061. }
  1062. void force_instantiate()const{}
  1063. };
  1064. static const init initializer;
  1065. static void force_instantiate()
  1066. {
  1067. initializer.force_instantiate();
  1068. }
  1069. };
  1070. template <class T>
  1071. const typename mpfi_initializer<T>::init mpfi_initializer<T>::initializer;
  1072. template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1073. struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
  1074. {
  1075. typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
  1076. template<int N>
  1077. static inline result_type const& get(const mpl::int_<N>&)
  1078. {
  1079. mpfi_initializer<result_type>::force_instantiate();
  1080. static result_type result;
  1081. static bool has_init = false;
  1082. if(!has_init)
  1083. {
  1084. has_init = true;
  1085. mpfi_const_pi(result.backend().data());
  1086. }
  1087. return result;
  1088. }
  1089. };
  1090. template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1091. struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
  1092. {
  1093. typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
  1094. template<int N>
  1095. static inline result_type const& get(const mpl::int_<N>&)
  1096. {
  1097. mpfi_initializer<result_type>::force_instantiate();
  1098. static result_type result;
  1099. static bool has_init = false;
  1100. if(!has_init)
  1101. {
  1102. has_init = true;
  1103. mpfi_const_log2(result.backend().data());
  1104. }
  1105. return result;
  1106. }
  1107. };
  1108. template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1109. struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
  1110. {
  1111. typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
  1112. template<int N>
  1113. static inline result_type const& get(const mpl::int_<N>&)
  1114. {
  1115. mpfi_initializer<result_type>::force_instantiate();
  1116. static result_type result;
  1117. static bool has_init = false;
  1118. if(!has_init)
  1119. {
  1120. has_init = true;
  1121. mpfi_const_euler(result.backend().data());
  1122. }
  1123. return result;
  1124. }
  1125. };
  1126. template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1127. struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
  1128. {
  1129. typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
  1130. template<int N>
  1131. static inline result_type const& get(const mpl::int_<N>&)
  1132. {
  1133. mpfi_initializer<result_type>::force_instantiate();
  1134. static result_type result;
  1135. static bool has_init = false;
  1136. if(!has_init)
  1137. {
  1138. has_init = true;
  1139. mpfi_const_catalan(result.backend().data());
  1140. }
  1141. return result;
  1142. }
  1143. };
  1144. }} // namespaces
  1145. }} // namespaces
  1146. namespace std{
  1147. //
  1148. // numeric_limits [partial] specializations for the types declared in this header:
  1149. //
  1150. template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1151. class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
  1152. {
  1153. typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> number_type;
  1154. public:
  1155. BOOST_STATIC_CONSTEXPR bool is_specialized = true;
  1156. static number_type (min)()
  1157. {
  1158. initializer.do_nothing();
  1159. static std::pair<bool, number_type> value;
  1160. if(!value.first)
  1161. {
  1162. value.first = true;
  1163. value.second = 0.5;
  1164. mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin());
  1165. }
  1166. return value.second;
  1167. }
  1168. static number_type (max)()
  1169. {
  1170. initializer.do_nothing();
  1171. static std::pair<bool, number_type> value;
  1172. if(!value.first)
  1173. {
  1174. value.first = true;
  1175. value.second = 0.5;
  1176. mpfi_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax());
  1177. }
  1178. return value.second;
  1179. }
  1180. BOOST_STATIC_CONSTEXPR number_type lowest()
  1181. {
  1182. return -(max)();
  1183. }
  1184. BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
  1185. BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
  1186. // Is this really correct???
  1187. BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2;
  1188. BOOST_STATIC_CONSTEXPR bool is_signed = true;
  1189. BOOST_STATIC_CONSTEXPR bool is_integer = false;
  1190. BOOST_STATIC_CONSTEXPR bool is_exact = false;
  1191. BOOST_STATIC_CONSTEXPR int radix = 2;
  1192. static number_type epsilon()
  1193. {
  1194. initializer.do_nothing();
  1195. static std::pair<bool, number_type> value;
  1196. if(!value.first)
  1197. {
  1198. value.first = true;
  1199. value.second = 1;
  1200. mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
  1201. }
  1202. return value.second;
  1203. }
  1204. // What value should this be????
  1205. static number_type round_error()
  1206. {
  1207. // returns epsilon/2
  1208. initializer.do_nothing();
  1209. static std::pair<bool, number_type> value;
  1210. if(!value.first)
  1211. {
  1212. value.first = true;
  1213. value.second = 1;
  1214. mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), 1);
  1215. }
  1216. return value.second;
  1217. }
  1218. BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
  1219. BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
  1220. BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
  1221. BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
  1222. BOOST_STATIC_CONSTEXPR bool has_infinity = true;
  1223. BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
  1224. BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
  1225. BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
  1226. BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
  1227. static number_type infinity()
  1228. {
  1229. initializer.do_nothing();
  1230. static std::pair<bool, number_type> value;
  1231. if(!value.first)
  1232. {
  1233. boost::multiprecision::mpfr_float_backend<Digits10> t;
  1234. mpfr_set_inf(t.data(), 1);
  1235. value.first = true;
  1236. mpfi_set_fr(value.second.backend().data(), t.data());
  1237. }
  1238. return value.second;
  1239. }
  1240. static number_type quiet_NaN()
  1241. {
  1242. initializer.do_nothing();
  1243. static std::pair<bool, number_type> value;
  1244. if(!value.first)
  1245. {
  1246. boost::multiprecision::mpfr_float_backend<Digits10> t;
  1247. mpfr_set_nan(t.data());
  1248. value.first = true;
  1249. mpfi_set_fr(value.second.backend().data(), t.data());
  1250. }
  1251. return value.second;
  1252. }
  1253. BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
  1254. {
  1255. return number_type(0);
  1256. }
  1257. BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
  1258. BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
  1259. BOOST_STATIC_CONSTEXPR bool is_bounded = true;
  1260. BOOST_STATIC_CONSTEXPR bool is_modulo = false;
  1261. BOOST_STATIC_CONSTEXPR bool traps = true;
  1262. BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
  1263. BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
  1264. private:
  1265. struct data_initializer
  1266. {
  1267. data_initializer()
  1268. {
  1269. std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::epsilon();
  1270. std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::round_error();
  1271. (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::min)();
  1272. (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::max)();
  1273. std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::infinity();
  1274. std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::quiet_NaN();
  1275. }
  1276. void do_nothing()const{}
  1277. };
  1278. static const data_initializer initializer;
  1279. };
  1280. template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1281. const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::initializer;
  1282. #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  1283. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1284. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits;
  1285. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1286. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits10;
  1287. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1288. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_digits10;
  1289. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1290. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_signed;
  1291. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1292. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_integer;
  1293. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1294. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_exact;
  1295. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1296. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::radix;
  1297. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1298. BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent;
  1299. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1300. BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent10;
  1301. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1302. BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent;
  1303. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1304. BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent10;
  1305. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1306. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_infinity;
  1307. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1308. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
  1309. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1310. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
  1311. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1312. BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm;
  1313. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1314. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm_loss;
  1315. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1316. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_iec559;
  1317. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1318. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_bounded;
  1319. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1320. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_modulo;
  1321. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1322. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::traps;
  1323. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1324. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::tinyness_before;
  1325. template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
  1326. BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::round_style;
  1327. #endif
  1328. template<boost::multiprecision::expression_template_option ExpressionTemplates>
  1329. class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >
  1330. {
  1331. typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> number_type;
  1332. public:
  1333. BOOST_STATIC_CONSTEXPR bool is_specialized = false;
  1334. static number_type (min)() { return number_type(0); }
  1335. static number_type (max)() { return number_type(0); }
  1336. static number_type lowest() { return number_type(0); }
  1337. BOOST_STATIC_CONSTEXPR int digits = 0;
  1338. BOOST_STATIC_CONSTEXPR int digits10 = 0;
  1339. BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
  1340. BOOST_STATIC_CONSTEXPR bool is_signed = false;
  1341. BOOST_STATIC_CONSTEXPR bool is_integer = false;
  1342. BOOST_STATIC_CONSTEXPR bool is_exact = false;
  1343. BOOST_STATIC_CONSTEXPR int radix = 0;
  1344. static number_type epsilon() { return number_type(0); }
  1345. static number_type round_error() { return number_type(0); }
  1346. BOOST_STATIC_CONSTEXPR int min_exponent = 0;
  1347. BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
  1348. BOOST_STATIC_CONSTEXPR int max_exponent = 0;
  1349. BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
  1350. BOOST_STATIC_CONSTEXPR bool has_infinity = false;
  1351. BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
  1352. BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
  1353. BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
  1354. BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
  1355. static number_type infinity() { return number_type(0); }
  1356. static number_type quiet_NaN() { return number_type(0); }
  1357. static number_type signaling_NaN() { return number_type(0); }
  1358. static number_type denorm_min() { return number_type(0); }
  1359. BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
  1360. BOOST_STATIC_CONSTEXPR bool is_bounded = false;
  1361. BOOST_STATIC_CONSTEXPR bool is_modulo = false;
  1362. BOOST_STATIC_CONSTEXPR bool traps = false;
  1363. BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
  1364. BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
  1365. };
  1366. #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  1367. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1368. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits;
  1369. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1370. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits10;
  1371. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1372. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_digits10;
  1373. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1374. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_signed;
  1375. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1376. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_integer;
  1377. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1378. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_exact;
  1379. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1380. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::radix;
  1381. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1382. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent;
  1383. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1384. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent10;
  1385. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1386. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent;
  1387. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1388. BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent10;
  1389. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1390. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_infinity;
  1391. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1392. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
  1393. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1394. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
  1395. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1396. BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm;
  1397. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1398. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
  1399. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1400. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_iec559;
  1401. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1402. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_bounded;
  1403. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1404. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_modulo;
  1405. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1406. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::traps;
  1407. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1408. BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::tinyness_before;
  1409. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  1410. BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::round_style;
  1411. #endif
  1412. } // namespace std
  1413. #endif