mpfi.hpp 73 KB

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