mpfr.hpp 201 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649
  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_MP_MPFR_HPP
  6. #define BOOST_MP_MPFR_HPP
  7. #include <boost/multiprecision/detail/standalone_config.hpp>
  8. #include <boost/multiprecision/number.hpp>
  9. #include <boost/multiprecision/debug_adaptor.hpp>
  10. #include <boost/multiprecision/logged_adaptor.hpp>
  11. #include <boost/multiprecision/gmp.hpp>
  12. #include <boost/multiprecision/detail/digits.hpp>
  13. #include <boost/multiprecision/detail/float128_functions.hpp>
  14. #include <boost/multiprecision/detail/atomic.hpp>
  15. #include <boost/multiprecision/traits/max_digits10.hpp>
  16. #include <boost/multiprecision/detail/hash.hpp>
  17. #include <boost/multiprecision/detail/no_exceptions_support.hpp>
  18. #include <boost/multiprecision/detail/assert.hpp>
  19. #include <boost/multiprecision/detail/fpclassify.hpp>
  20. #include <mpfr.h>
  21. #include <cmath>
  22. #include <cstdint>
  23. #include <algorithm>
  24. #include <utility>
  25. #include <type_traits>
  26. #include <atomic>
  27. #ifdef BOOST_MP_MATH_AVAILABLE
  28. #include <boost/math/constants/constants.hpp>
  29. #include <boost/math/special_functions/gamma.hpp>
  30. #endif
  31. #ifndef BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION
  32. #define BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION 20
  33. #endif
  34. namespace boost {
  35. namespace multiprecision {
  36. template <unsigned digits10, mpfr_allocation_type AllocationType>
  37. struct number_category<backends::mpfr_float_backend<digits10, AllocationType> > : public std::integral_constant<int, number_kind_floating_point>
  38. {};
  39. namespace backends {
  40. namespace detail {
  41. template <bool b>
  42. struct mpfr_cleanup
  43. {
  44. //
  45. // There are 2 seperate cleanup objects here, one calls
  46. // mpfr_free_cache on destruction to perform global cleanup
  47. // the other is declared thread_local and calls
  48. // mpfr_free_cache2(MPFR_FREE_LOCAL_CACHE) to free thread local data.
  49. //
  50. struct initializer
  51. {
  52. initializer() {}
  53. ~initializer() { mpfr_free_cache(); }
  54. void force_instantiate() const {}
  55. };
  56. #if MPFR_VERSION_MAJOR >= 4
  57. struct thread_initializer
  58. {
  59. thread_initializer() {}
  60. ~thread_initializer() { mpfr_free_cache2(MPFR_FREE_LOCAL_CACHE); }
  61. void force_instantiate() const {}
  62. };
  63. #endif
  64. static const initializer init;
  65. static void force_instantiate()
  66. {
  67. #if MPFR_VERSION_MAJOR >= 4
  68. static const BOOST_MP_THREAD_LOCAL thread_initializer thread_init;
  69. thread_init.force_instantiate();
  70. #endif
  71. init.force_instantiate();
  72. }
  73. };
  74. template <bool b>
  75. typename mpfr_cleanup<b>::initializer const mpfr_cleanup<b>::init;
  76. inline void mpfr_copy_precision(mpfr_t dest, const mpfr_t src)
  77. {
  78. mpfr_prec_t p_dest = mpfr_get_prec(dest);
  79. mpfr_prec_t p_src = mpfr_get_prec(src);
  80. if (p_dest != p_src)
  81. mpfr_set_prec(dest, p_src);
  82. }
  83. inline void mpfr_copy_precision(mpfr_t dest, const mpfr_t src1, const mpfr_t src2)
  84. {
  85. mpfr_prec_t p_dest = mpfr_get_prec(dest);
  86. mpfr_prec_t p_src1 = mpfr_get_prec(src1);
  87. mpfr_prec_t p_src2 = mpfr_get_prec(src2);
  88. if (p_src2 > p_src1)
  89. p_src1 = p_src2;
  90. if (p_dest != p_src1)
  91. mpfr_set_prec(dest, p_src1);
  92. }
  93. template <unsigned digits10, mpfr_allocation_type AllocationType>
  94. struct mpfr_float_imp;
  95. template <unsigned digits10>
  96. struct mpfr_float_imp<digits10, allocate_dynamic>
  97. {
  98. #ifdef BOOST_HAS_LONG_LONG
  99. using signed_types = std::tuple<long, long long> ;
  100. using unsigned_types = std::tuple<unsigned long, unsigned long long>;
  101. #else
  102. using signed_types = std::tuple<long> ;
  103. using unsigned_types = std::tuple<unsigned long>;
  104. #endif
  105. using float_types = std::tuple<double, long double>;
  106. using exponent_type = long ;
  107. mpfr_float_imp()
  108. {
  109. mpfr_init2(m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision()))));
  110. mpfr_set_ui(m_data, 0u, GMP_RNDN);
  111. }
  112. mpfr_float_imp(unsigned digits2)
  113. {
  114. mpfr_init2(m_data, digits2);
  115. mpfr_set_ui(m_data, 0u, GMP_RNDN);
  116. }
  117. mpfr_float_imp(const mpfr_float_imp& o)
  118. {
  119. mpfr_init2(m_data, preserve_source_precision() ? mpfr_get_prec(o.data()) : static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision())));
  120. if (o.m_data[0]._mpfr_d)
  121. mpfr_set(m_data, o.m_data, GMP_RNDN);
  122. }
  123. // rvalue copy
  124. mpfr_float_imp(mpfr_float_imp&& o) noexcept
  125. {
  126. mpfr_prec_t binary_default_precision = static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision()));
  127. if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpfr_get_prec(o.data()) == binary_default_precision))
  128. {
  129. m_data[0] = o.m_data[0];
  130. o.m_data[0]._mpfr_d = nullptr;
  131. }
  132. else
  133. {
  134. // NOTE: C allocation interface must not throw:
  135. mpfr_init2(m_data, binary_default_precision);
  136. if (o.m_data[0]._mpfr_d)
  137. mpfr_set(m_data, o.m_data, GMP_RNDN);
  138. }
  139. }
  140. mpfr_float_imp& operator=(const mpfr_float_imp& o)
  141. {
  142. if ((o.m_data[0]._mpfr_d) && (this != &o))
  143. {
  144. if (m_data[0]._mpfr_d == nullptr)
  145. {
  146. mpfr_init2(m_data, preserve_source_precision() ? static_cast<mpfr_prec_t>(mpfr_get_prec(o.m_data)) : static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision())));
  147. }
  148. else if (preserve_source_precision() && (mpfr_get_prec(o.data()) != mpfr_get_prec(data())))
  149. {
  150. mpfr_set_prec(m_data, mpfr_get_prec(o.m_data));
  151. }
  152. mpfr_set(m_data, o.m_data, GMP_RNDN);
  153. }
  154. return *this;
  155. }
  156. // rvalue assign
  157. mpfr_float_imp& operator=(mpfr_float_imp&& o) noexcept
  158. {
  159. if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpfr_get_prec(o.data()) == mpfr_get_prec(data())))
  160. mpfr_swap(m_data, o.m_data);
  161. else
  162. *this = static_cast<const mpfr_float_imp&>(o);
  163. return *this;
  164. }
  165. #ifdef BOOST_HAS_LONG_LONG
  166. #ifdef _MPFR_H_HAVE_INTMAX_T
  167. mpfr_float_imp& operator=(unsigned long long i)
  168. {
  169. if (m_data[0]._mpfr_d == nullptr)
  170. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  171. mpfr_set_uj(m_data, i, GMP_RNDN);
  172. return *this;
  173. }
  174. mpfr_float_imp& operator=(long long i)
  175. {
  176. if (m_data[0]._mpfr_d == nullptr)
  177. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  178. mpfr_set_sj(m_data, i, GMP_RNDN);
  179. return *this;
  180. }
  181. #else
  182. mpfr_float_imp& operator=(unsigned long long i)
  183. {
  184. if (m_data[0]._mpfr_d == nullptr)
  185. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  186. unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
  187. unsigned shift = 0;
  188. mpfr_t t;
  189. mpfr_init2(t, (std::max)(static_cast<mpfr_prec_t>(std::numeric_limits<unsigned long long>::digits), static_cast<mpfr_prec_t>(mpfr_get_prec(m_data))));
  190. mpfr_set_ui(m_data, 0, GMP_RNDN);
  191. while (i)
  192. {
  193. mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
  194. if (shift)
  195. mpfr_mul_2exp(t, t, shift, GMP_RNDN);
  196. mpfr_add(m_data, m_data, t, GMP_RNDN);
  197. shift += std::numeric_limits<unsigned long>::digits;
  198. i >>= std::numeric_limits<unsigned long>::digits;
  199. }
  200. mpfr_clear(t);
  201. return *this;
  202. }
  203. mpfr_float_imp& operator=(long long i)
  204. {
  205. if (m_data[0]._mpfr_d == nullptr)
  206. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  207. bool neg = i < 0;
  208. *this = boost::multiprecision::detail::unsigned_abs(i);
  209. if (neg)
  210. mpfr_neg(m_data, m_data, GMP_RNDN);
  211. return *this;
  212. }
  213. #endif
  214. #endif
  215. #ifdef BOOST_HAS_INT128
  216. mpfr_float_imp& operator=(uint128_type i)
  217. {
  218. if (m_data[0]._mpfr_d == nullptr)
  219. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  220. unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
  221. unsigned shift = 0;
  222. mpfr_t t;
  223. mpfr_init2(t, (std::max)(static_cast<mpfr_prec_t>(std::numeric_limits<unsigned long long>::digits), static_cast<mpfr_prec_t>(mpfr_get_prec(m_data))));
  224. mpfr_set_ui(m_data, 0, GMP_RNDN);
  225. while (i)
  226. {
  227. mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
  228. if (shift)
  229. mpfr_mul_2exp(t, t, shift, GMP_RNDN);
  230. mpfr_add(m_data, m_data, t, GMP_RNDN);
  231. shift += std::numeric_limits<unsigned long>::digits;
  232. i >>= std::numeric_limits<unsigned long>::digits;
  233. }
  234. mpfr_clear(t);
  235. return *this;
  236. }
  237. mpfr_float_imp& operator=(int128_type i)
  238. {
  239. if (m_data[0]._mpfr_d == nullptr)
  240. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  241. bool neg = i < 0;
  242. *this = boost::multiprecision::detail::unsigned_abs(i);
  243. if (neg)
  244. mpfr_neg(m_data, m_data, GMP_RNDN);
  245. return *this;
  246. }
  247. #endif
  248. mpfr_float_imp& operator=(unsigned long i)
  249. {
  250. if (m_data[0]._mpfr_d == nullptr)
  251. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  252. mpfr_set_ui(m_data, i, GMP_RNDN);
  253. return *this;
  254. }
  255. mpfr_float_imp& operator=(long i)
  256. {
  257. if (m_data[0]._mpfr_d == nullptr)
  258. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  259. mpfr_set_si(m_data, i, GMP_RNDN);
  260. return *this;
  261. }
  262. mpfr_float_imp& operator=(double d)
  263. {
  264. if (m_data[0]._mpfr_d == nullptr)
  265. mpfr_init2(m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision()))));
  266. mpfr_set_d(m_data, d, GMP_RNDN);
  267. return *this;
  268. }
  269. mpfr_float_imp& operator=(long double a)
  270. {
  271. if (m_data[0]._mpfr_d == nullptr)
  272. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  273. mpfr_set_ld(m_data, a, GMP_RNDN);
  274. return *this;
  275. }
  276. #ifdef BOOST_HAS_FLOAT128
  277. mpfr_float_imp& operator=(float128_type a)
  278. {
  279. BOOST_MP_FLOAT128_USING
  280. if (m_data[0]._mpfr_d == nullptr)
  281. mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision())));
  282. if (a == 0)
  283. {
  284. mpfr_set_si(m_data, 0, GMP_RNDN);
  285. return *this;
  286. }
  287. if (a == 1)
  288. {
  289. mpfr_set_si(m_data, 1, GMP_RNDN);
  290. return *this;
  291. }
  292. if (BOOST_MP_ISINF(a))
  293. {
  294. mpfr_set_inf(m_data, a < 0 ? -1 : 1);
  295. return *this;
  296. }
  297. if (BOOST_MP_ISNAN(a))
  298. {
  299. mpfr_set_nan(m_data);
  300. return *this;
  301. }
  302. int e;
  303. float128_type f, term;
  304. mpfr_set_ui(m_data, 0u, GMP_RNDN);
  305. f = frexp(a, &e);
  306. constexpr const int shift = std::numeric_limits<int>::digits - 1;
  307. while (f)
  308. {
  309. // extract int sized bits from f:
  310. f = ldexp(f, shift);
  311. term = floor(f);
  312. e -= shift;
  313. mpfr_mul_2exp(m_data, m_data, shift, GMP_RNDN);
  314. if (term > 0)
  315. mpfr_add_ui(m_data, m_data, static_cast<unsigned>(term), GMP_RNDN);
  316. else
  317. mpfr_sub_ui(m_data, m_data, static_cast<unsigned>(-term), GMP_RNDN);
  318. f -= term;
  319. }
  320. if (e > 0)
  321. mpfr_mul_2exp(m_data, m_data, e, GMP_RNDN);
  322. else if (e < 0)
  323. mpfr_div_2exp(m_data, m_data, -e, GMP_RNDN);
  324. return *this;
  325. }
  326. #endif
  327. mpfr_float_imp& operator=(const char* s)
  328. {
  329. if (m_data[0]._mpfr_d == nullptr)
  330. mpfr_init2(m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(digits10 ? digits10 : static_cast<unsigned>(get_default_precision()))));
  331. if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
  332. {
  333. BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
  334. }
  335. return *this;
  336. }
  337. void swap(mpfr_float_imp& o) noexcept
  338. {
  339. mpfr_swap(m_data, o.m_data);
  340. }
  341. std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
  342. {
  343. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  344. bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
  345. bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
  346. std::streamsize org_digits(digits);
  347. if (scientific && digits)
  348. ++digits;
  349. std::string result;
  350. mp_exp_t e;
  351. if (mpfr_inf_p(m_data))
  352. {
  353. if (mpfr_sgn(m_data) < 0)
  354. result = "-inf";
  355. else if (f & std::ios_base::showpos)
  356. result = "+inf";
  357. else
  358. result = "inf";
  359. return result;
  360. }
  361. if (mpfr_nan_p(m_data))
  362. {
  363. result = "nan";
  364. return result;
  365. }
  366. if (mpfr_zero_p(m_data))
  367. {
  368. e = 0;
  369. if (mpfr_signbit(m_data))
  370. result = "-0";
  371. else
  372. result = "0";
  373. }
  374. else if (fixed)
  375. {
  376. // We actually need a different number of digits to what one might expect:
  377. char* ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  378. --e;
  379. mpfr_free_str(ps);
  380. digits += e + 1;
  381. if (digits == 0)
  382. {
  383. // We need to get *all* the digits and then possibly round up,
  384. // we end up with either "0" or "1" as the result.
  385. ps = mpfr_get_str(nullptr, &e, 10, 0, m_data, GMP_RNDN);
  386. --e;
  387. unsigned offset = *ps == '-' ? 1 : 0;
  388. if (ps[offset] > '5')
  389. {
  390. ++e;
  391. ps[offset] = '1';
  392. ps[offset + 1] = 0;
  393. }
  394. else if (ps[offset] == '5')
  395. {
  396. unsigned i = offset + 1;
  397. bool round_up = false;
  398. while (ps[i] != 0)
  399. {
  400. if (ps[i] != '0')
  401. {
  402. round_up = true;
  403. break;
  404. }
  405. ++i;
  406. }
  407. if (round_up)
  408. {
  409. ++e;
  410. ps[offset] = '1';
  411. ps[offset + 1] = 0;
  412. }
  413. else
  414. {
  415. ps[offset] = '0';
  416. ps[offset + 1] = 0;
  417. }
  418. }
  419. else
  420. {
  421. ps[offset] = '0';
  422. ps[offset + 1] = 0;
  423. }
  424. }
  425. else if (digits > 0)
  426. {
  427. mp_exp_t old_e = e;
  428. ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  429. --e; // To match with what our formatter expects.
  430. if (old_e > e)
  431. {
  432. // in some cases, when we ask for more digits of precision, it will
  433. // change the number of digits to the left of the decimal, if that
  434. // happens, account for it here.
  435. // example: cout << fixed << setprecision(3) << mpf_float_50("99.9809")
  436. mpfr_free_str(ps);
  437. digits -= old_e - e;
  438. ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  439. --e; // To match with what our formatter expects.
  440. }
  441. }
  442. else
  443. {
  444. ps = mpfr_get_str(nullptr, &e, 10, 1, m_data, GMP_RNDN);
  445. --e;
  446. unsigned offset = *ps == '-' ? 1 : 0;
  447. ps[offset] = '0';
  448. ps[offset + 1] = 0;
  449. }
  450. result = ps ? ps : "0";
  451. if (ps)
  452. mpfr_free_str(ps);
  453. }
  454. else
  455. {
  456. char* ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  457. --e; // To match with what our formatter expects.
  458. result = ps ? ps : "0";
  459. if (ps)
  460. mpfr_free_str(ps);
  461. }
  462. boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
  463. return result;
  464. }
  465. ~mpfr_float_imp() noexcept
  466. {
  467. if (m_data[0]._mpfr_d)
  468. mpfr_clear(m_data);
  469. detail::mpfr_cleanup<true>::force_instantiate();
  470. }
  471. void negate() noexcept
  472. {
  473. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  474. mpfr_neg(m_data, m_data, GMP_RNDN);
  475. }
  476. template <mpfr_allocation_type AllocationType>
  477. int compare(const mpfr_float_backend<digits10, AllocationType>& o) const
  478. {
  479. BOOST_MP_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d);
  480. return mpfr_cmp(m_data, o.m_data);
  481. }
  482. int compare(long i) const
  483. {
  484. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  485. return mpfr_cmp_si(m_data, i);
  486. }
  487. int compare(double i) const
  488. {
  489. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  490. return mpfr_cmp_d(m_data, i);
  491. }
  492. int compare(long double i) const
  493. {
  494. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  495. return mpfr_cmp_ld(m_data, i);
  496. }
  497. int compare(unsigned long i) const
  498. {
  499. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  500. return mpfr_cmp_ui(m_data, i);
  501. }
  502. template <class V>
  503. int compare(V v) const
  504. {
  505. mpfr_float_backend<digits10, allocate_dynamic> d(0uL, mpfr_get_prec(m_data));
  506. d = v;
  507. return compare(d);
  508. }
  509. mpfr_t& data() noexcept
  510. {
  511. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  512. return m_data;
  513. }
  514. const mpfr_t& data() const noexcept
  515. {
  516. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  517. return m_data;
  518. }
  519. protected:
  520. mpfr_t m_data;
  521. static boost::multiprecision::detail::precision_type& get_global_default_precision() noexcept
  522. {
  523. static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION);
  524. return val;
  525. }
  526. static unsigned& get_default_precision() noexcept
  527. {
  528. static BOOST_MP_THREAD_LOCAL unsigned val(get_global_default_precision());
  529. return val;
  530. }
  531. #ifndef BOOST_MT_NO_ATOMIC_INT
  532. static std::atomic<variable_precision_options>& get_global_default_options() noexcept
  533. {
  534. static std::atomic<variable_precision_options> val{variable_precision_options::preserve_related_precision};
  535. return val;
  536. }
  537. #else
  538. static variable_precision_options& get_global_default_options() noexcept
  539. {
  540. static variable_precision_options val{variable_precision_options::preserve_related_precision};
  541. return val;
  542. }
  543. #endif
  544. static variable_precision_options& get_default_options()noexcept
  545. {
  546. static BOOST_MP_THREAD_LOCAL variable_precision_options val(get_global_default_options());
  547. return val;
  548. }
  549. static bool preserve_source_precision() noexcept
  550. {
  551. return get_default_options() >= variable_precision_options::preserve_source_precision;
  552. }
  553. };
  554. #ifdef BOOST_MSVC
  555. #pragma warning(push)
  556. #pragma warning(disable : 4127) // Conditional expression is constant
  557. #endif
  558. template <unsigned digits10>
  559. struct mpfr_float_imp<digits10, allocate_stack>
  560. {
  561. #ifdef BOOST_HAS_LONG_LONG
  562. using signed_types = std::tuple<long, long long> ;
  563. using unsigned_types = std::tuple<unsigned long, unsigned long long>;
  564. #else
  565. using signed_types = std::tuple<long> ;
  566. using unsigned_types = std::tuple<unsigned long>;
  567. #endif
  568. using float_types = std::tuple<double, long double>;
  569. using exponent_type = long ;
  570. static constexpr const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u);
  571. static constexpr const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t);
  572. ~mpfr_float_imp() noexcept
  573. {
  574. detail::mpfr_cleanup<true>::force_instantiate();
  575. }
  576. mpfr_float_imp()
  577. {
  578. mpfr_custom_init(m_buffer, digits2);
  579. mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
  580. mpfr_set_ui(m_data, 0u, GMP_RNDN);
  581. }
  582. mpfr_float_imp(const mpfr_float_imp& o)
  583. {
  584. mpfr_custom_init(m_buffer, digits2);
  585. mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
  586. mpfr_set(m_data, o.m_data, GMP_RNDN);
  587. }
  588. mpfr_float_imp& operator=(const mpfr_float_imp& o)
  589. {
  590. mpfr_set(m_data, o.m_data, GMP_RNDN);
  591. return *this;
  592. }
  593. #ifdef BOOST_HAS_LONG_LONG
  594. #ifdef _MPFR_H_HAVE_INTMAX_T
  595. mpfr_float_imp& operator=(unsigned long long i)
  596. {
  597. mpfr_set_uj(m_data, i, GMP_RNDN);
  598. return *this;
  599. }
  600. mpfr_float_imp& operator=(long long i)
  601. {
  602. mpfr_set_sj(m_data, i, GMP_RNDN);
  603. return *this;
  604. }
  605. #else
  606. mpfr_float_imp& operator=(unsigned long long i)
  607. {
  608. unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL);
  609. unsigned shift = 0;
  610. mpfr_t t;
  611. mp_limb_t t_limbs[limb_count];
  612. mpfr_custom_init(t_limbs, digits2);
  613. mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
  614. mpfr_set_ui(m_data, 0, GMP_RNDN);
  615. while (i)
  616. {
  617. mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
  618. if (shift)
  619. mpfr_mul_2exp(t, t, shift, GMP_RNDN);
  620. mpfr_add(m_data, m_data, t, GMP_RNDN);
  621. shift += std::numeric_limits<unsigned long>::digits;
  622. i >>= std::numeric_limits<unsigned long>::digits;
  623. }
  624. return *this;
  625. }
  626. mpfr_float_imp& operator=(long long i)
  627. {
  628. bool neg = i < 0;
  629. *this = boost::multiprecision::detail::unsigned_abs(i);
  630. if (neg)
  631. mpfr_neg(m_data, m_data, GMP_RNDN);
  632. return *this;
  633. }
  634. #endif
  635. #endif
  636. #ifdef BOOST_HAS_INT128
  637. mpfr_float_imp& operator=(uint128_type i)
  638. {
  639. unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL);
  640. unsigned shift = 0;
  641. mpfr_t t;
  642. mp_limb_t t_limbs[limb_count];
  643. mpfr_custom_init(t_limbs, digits2);
  644. mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
  645. mpfr_set_ui(m_data, 0, GMP_RNDN);
  646. while (i)
  647. {
  648. mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
  649. if (shift)
  650. mpfr_mul_2exp(t, t, shift, GMP_RNDN);
  651. mpfr_add(m_data, m_data, t, GMP_RNDN);
  652. shift += std::numeric_limits<unsigned long>::digits;
  653. i >>= std::numeric_limits<unsigned long>::digits;
  654. }
  655. return *this;
  656. }
  657. mpfr_float_imp& operator=(int128_type i)
  658. {
  659. bool neg = i < 0;
  660. *this = boost::multiprecision::detail::unsigned_abs(i);
  661. if (neg)
  662. mpfr_neg(m_data, m_data, GMP_RNDN);
  663. return *this;
  664. }
  665. #endif
  666. mpfr_float_imp& operator=(unsigned long i)
  667. {
  668. mpfr_set_ui(m_data, i, GMP_RNDN);
  669. return *this;
  670. }
  671. mpfr_float_imp& operator=(long i)
  672. {
  673. mpfr_set_si(m_data, i, GMP_RNDN);
  674. return *this;
  675. }
  676. mpfr_float_imp& operator=(double d)
  677. {
  678. mpfr_set_d(m_data, d, GMP_RNDN);
  679. return *this;
  680. }
  681. mpfr_float_imp& operator=(long double a)
  682. {
  683. mpfr_set_ld(m_data, a, GMP_RNDN);
  684. return *this;
  685. }
  686. #ifdef BOOST_HAS_FLOAT128
  687. mpfr_float_imp& operator=(float128_type a)
  688. {
  689. BOOST_MP_FLOAT128_USING
  690. if (a == 0)
  691. {
  692. mpfr_set_si(m_data, 0, GMP_RNDN);
  693. return *this;
  694. }
  695. if (a == 1)
  696. {
  697. mpfr_set_si(m_data, 1, GMP_RNDN);
  698. return *this;
  699. }
  700. if (BOOST_MP_ISINF(a))
  701. {
  702. mpfr_set_inf(m_data, a < 0 ? -1 : 1);
  703. return *this;
  704. }
  705. if (BOOST_MP_ISNAN(a))
  706. {
  707. mpfr_set_nan(m_data);
  708. return *this;
  709. }
  710. int e;
  711. float128_type f, term;
  712. mpfr_set_ui(m_data, 0u, GMP_RNDN);
  713. f = frexp(a, &e);
  714. constexpr const int shift = std::numeric_limits<int>::digits - 1;
  715. while (f)
  716. {
  717. // extract int sized bits from f:
  718. f = ldexp(f, shift);
  719. term = floor(f);
  720. e -= shift;
  721. mpfr_mul_2exp(m_data, m_data, shift, GMP_RNDN);
  722. if (term > 0)
  723. mpfr_add_ui(m_data, m_data, static_cast<unsigned>(term), GMP_RNDN);
  724. else
  725. mpfr_sub_ui(m_data, m_data, static_cast<unsigned>(-term), GMP_RNDN);
  726. f -= term;
  727. }
  728. if (e > 0)
  729. mpfr_mul_2exp(m_data, m_data, e, GMP_RNDN);
  730. else if (e < 0)
  731. mpfr_div_2exp(m_data, m_data, -e, GMP_RNDN);
  732. return *this;
  733. }
  734. #endif
  735. mpfr_float_imp& operator=(const char* s)
  736. {
  737. if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
  738. {
  739. BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
  740. }
  741. return *this;
  742. }
  743. void swap(mpfr_float_imp& o) noexcept
  744. {
  745. // We have to swap by copying:
  746. mpfr_float_imp t(*this);
  747. *this = o;
  748. o = t;
  749. }
  750. std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
  751. {
  752. BOOST_MP_ASSERT(m_data[0]._mpfr_d);
  753. bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
  754. bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
  755. std::streamsize org_digits(digits);
  756. if (scientific && digits)
  757. ++digits;
  758. std::string result;
  759. mp_exp_t e;
  760. if (mpfr_inf_p(m_data))
  761. {
  762. if (mpfr_sgn(m_data) < 0)
  763. result = "-inf";
  764. else if (f & std::ios_base::showpos)
  765. result = "+inf";
  766. else
  767. result = "inf";
  768. return result;
  769. }
  770. if (mpfr_nan_p(m_data))
  771. {
  772. result = "nan";
  773. return result;
  774. }
  775. if (mpfr_zero_p(m_data))
  776. {
  777. e = 0;
  778. result = "0";
  779. }
  780. else
  781. {
  782. char* ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  783. --e; // To match with what our formatter expects.
  784. if (fixed && e != -1)
  785. {
  786. // Oops we actually need a different number of digits to what we asked for:
  787. mpfr_free_str(ps);
  788. digits += e + 1;
  789. if (digits == 0)
  790. {
  791. // We need to get *all* the digits and then possibly round up,
  792. // we end up with either "0" or "1" as the result.
  793. ps = mpfr_get_str(nullptr, &e, 10, 0, m_data, GMP_RNDN);
  794. --e;
  795. unsigned offset = *ps == '-' ? 1 : 0;
  796. if (ps[offset] > '5')
  797. {
  798. ++e;
  799. ps[offset] = '1';
  800. ps[offset + 1] = 0;
  801. }
  802. else if (ps[offset] == '5')
  803. {
  804. unsigned i = offset + 1;
  805. bool round_up = false;
  806. while (ps[i] != 0)
  807. {
  808. if (ps[i] != '0')
  809. {
  810. round_up = true;
  811. break;
  812. }
  813. ++i;
  814. }
  815. if (round_up)
  816. {
  817. ++e;
  818. ps[offset] = '1';
  819. ps[offset + 1] = 0;
  820. }
  821. else
  822. {
  823. ps[offset] = '0';
  824. ps[offset + 1] = 0;
  825. }
  826. }
  827. else
  828. {
  829. ps[offset] = '0';
  830. ps[offset + 1] = 0;
  831. }
  832. }
  833. else if (digits > 0)
  834. {
  835. ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  836. --e; // To match with what our formatter expects.
  837. }
  838. else
  839. {
  840. ps = mpfr_get_str(nullptr, &e, 10, 1, m_data, GMP_RNDN);
  841. --e;
  842. unsigned offset = *ps == '-' ? 1 : 0;
  843. ps[offset] = '0';
  844. ps[offset + 1] = 0;
  845. }
  846. }
  847. result = ps ? ps : "0";
  848. if (ps)
  849. mpfr_free_str(ps);
  850. }
  851. boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
  852. return result;
  853. }
  854. void negate() noexcept
  855. {
  856. mpfr_neg(m_data, m_data, GMP_RNDN);
  857. }
  858. template <mpfr_allocation_type AllocationType>
  859. int compare(const mpfr_float_backend<digits10, AllocationType>& o) const
  860. {
  861. return mpfr_cmp(m_data, o.m_data);
  862. }
  863. int compare(long i) const
  864. {
  865. return mpfr_cmp_si(m_data, i);
  866. }
  867. int compare(unsigned long i) const
  868. {
  869. return mpfr_cmp_ui(m_data, i);
  870. }
  871. int compare(double i) const
  872. {
  873. return mpfr_cmp_d(m_data, i);
  874. }
  875. int compare(long double i) const
  876. {
  877. return mpfr_cmp_ld(m_data, i);
  878. }
  879. template <class V>
  880. int compare(V v) const
  881. {
  882. mpfr_float_backend<digits10, allocate_stack> d;
  883. d = v;
  884. return compare(d);
  885. }
  886. mpfr_t& data() noexcept
  887. {
  888. return m_data;
  889. }
  890. const mpfr_t& data() const noexcept
  891. {
  892. return m_data;
  893. }
  894. protected:
  895. mpfr_t m_data;
  896. mp_limb_t m_buffer[limb_count];
  897. };
  898. #ifdef BOOST_MSVC
  899. #pragma warning(pop)
  900. #endif
  901. } // namespace detail
  902. template <unsigned digits10, mpfr_allocation_type AllocationType>
  903. struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
  904. {
  905. mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
  906. mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
  907. // rvalue copy
  908. mpfr_float_backend(mpfr_float_backend&& o) noexcept : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o))
  909. {}
  910. template <unsigned D, mpfr_allocation_type AT>
  911. mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
  912. : detail::mpfr_float_imp<digits10, AllocationType>()
  913. {
  914. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  915. }
  916. template <unsigned D, mpfr_allocation_type AT>
  917. explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
  918. : detail::mpfr_float_imp<digits10, AllocationType>()
  919. {
  920. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  921. }
  922. template <unsigned D>
  923. mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
  924. : detail::mpfr_float_imp<digits10, AllocationType>()
  925. {
  926. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  927. }
  928. template <unsigned D>
  929. mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
  930. : detail::mpfr_float_imp<digits10, AllocationType>()
  931. {
  932. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  933. }
  934. mpfr_float_backend(const gmp_int& val)
  935. : detail::mpfr_float_imp<digits10, AllocationType>()
  936. {
  937. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  938. }
  939. mpfr_float_backend(const gmp_rational& val)
  940. : detail::mpfr_float_imp<digits10, AllocationType>()
  941. {
  942. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  943. }
  944. mpfr_float_backend(const mpfr_t val)
  945. : detail::mpfr_float_imp<digits10, AllocationType>()
  946. {
  947. mpfr_set(this->m_data, val, GMP_RNDN);
  948. }
  949. mpfr_float_backend(const mpf_t val)
  950. : detail::mpfr_float_imp<digits10, AllocationType>()
  951. {
  952. mpfr_set_f(this->m_data, val, GMP_RNDN);
  953. }
  954. mpfr_float_backend(const mpz_t val)
  955. : detail::mpfr_float_imp<digits10, AllocationType>()
  956. {
  957. mpfr_set_z(this->m_data, val, GMP_RNDN);
  958. }
  959. mpfr_float_backend(const mpq_t val)
  960. : detail::mpfr_float_imp<digits10, AllocationType>()
  961. {
  962. mpfr_set_q(this->m_data, val, GMP_RNDN);
  963. }
  964. // Construction with precision: we ignore the precision here.
  965. template <class V>
  966. mpfr_float_backend(const V& o, unsigned)
  967. {
  968. *this = o;
  969. }
  970. mpfr_float_backend& operator=(const mpfr_float_backend& o)
  971. {
  972. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
  973. return *this;
  974. }
  975. // rvalue assign
  976. mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept
  977. {
  978. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
  979. return *this;
  980. }
  981. template <class V>
  982. typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<digits10, AllocationType>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
  983. {
  984. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
  985. return *this;
  986. }
  987. mpfr_float_backend& operator=(const mpfr_t val)
  988. {
  989. if (this->m_data[0]._mpfr_d == nullptr)
  990. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  991. mpfr_set(this->m_data, val, GMP_RNDN);
  992. return *this;
  993. }
  994. mpfr_float_backend& operator=(const mpf_t val)
  995. {
  996. if (this->m_data[0]._mpfr_d == nullptr)
  997. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  998. mpfr_set_f(this->m_data, val, GMP_RNDN);
  999. return *this;
  1000. }
  1001. mpfr_float_backend& operator=(const mpz_t val)
  1002. {
  1003. if (this->m_data[0]._mpfr_d == nullptr)
  1004. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1005. mpfr_set_z(this->m_data, val, GMP_RNDN);
  1006. return *this;
  1007. }
  1008. mpfr_float_backend& operator=(const mpq_t val)
  1009. {
  1010. if (this->m_data[0]._mpfr_d == nullptr)
  1011. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1012. mpfr_set_q(this->m_data, val, GMP_RNDN);
  1013. return *this;
  1014. }
  1015. // We don't change our precision here, this is a fixed precision type:
  1016. template <unsigned D, mpfr_allocation_type AT>
  1017. mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
  1018. {
  1019. if (this->m_data[0]._mpfr_d == nullptr)
  1020. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1021. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  1022. return *this;
  1023. }
  1024. template <unsigned D>
  1025. mpfr_float_backend& operator=(const gmp_float<D>& val)
  1026. {
  1027. if (this->m_data[0]._mpfr_d == nullptr)
  1028. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1029. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  1030. return *this;
  1031. }
  1032. mpfr_float_backend& operator=(const gmp_int& val)
  1033. {
  1034. if (this->m_data[0]._mpfr_d == nullptr)
  1035. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1036. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  1037. return *this;
  1038. }
  1039. mpfr_float_backend& operator=(const gmp_rational& val)
  1040. {
  1041. if (this->m_data[0]._mpfr_d == nullptr)
  1042. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1043. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  1044. return *this;
  1045. }
  1046. };
  1047. template <>
  1048. struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
  1049. {
  1050. mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
  1051. mpfr_float_backend(const mpfr_t val)
  1052. : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(mpfr_get_prec(val)) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(get_default_precision())))
  1053. {
  1054. mpfr_set(this->m_data, val, GMP_RNDN);
  1055. }
  1056. mpfr_float_backend(const mpf_t val)
  1057. : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(mpf_get_prec(val)) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(get_default_precision())))
  1058. {
  1059. mpfr_set_f(this->m_data, val, GMP_RNDN);
  1060. }
  1061. mpfr_float_backend(const mpz_t val)
  1062. : detail::mpfr_float_imp<0, allocate_dynamic>()
  1063. {
  1064. mpfr_set_z(this->m_data, val, GMP_RNDN);
  1065. }
  1066. mpfr_float_backend(const mpq_t val)
  1067. : detail::mpfr_float_imp<0, allocate_dynamic>()
  1068. {
  1069. mpfr_set_q(this->m_data, val, GMP_RNDN);
  1070. }
  1071. mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
  1072. // rvalue copy
  1073. mpfr_float_backend(mpfr_float_backend&& o) noexcept : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o))
  1074. {}
  1075. template <class V>
  1076. mpfr_float_backend(const V& o, unsigned digits10)
  1077. : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
  1078. {
  1079. *this = o;
  1080. }
  1081. #ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
  1082. mpfr_float_backend(const std::string_view& o, unsigned digits10)
  1083. : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
  1084. {
  1085. std::string s(o);
  1086. *this = s.c_str();
  1087. }
  1088. #endif
  1089. template <unsigned D>
  1090. mpfr_float_backend(const gmp_float<D>& val, unsigned digits10)
  1091. : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
  1092. {
  1093. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  1094. }
  1095. template <unsigned D>
  1096. mpfr_float_backend(const mpfr_float_backend<D>& val, unsigned digits10)
  1097. : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
  1098. {
  1099. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  1100. }
  1101. template <unsigned D>
  1102. mpfr_float_backend(const mpfr_float_backend<D>& val)
  1103. : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_related_precision() ? static_cast<unsigned>(mpfr_get_prec(val.data())) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(get_default_precision())))
  1104. {
  1105. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  1106. }
  1107. template <unsigned D>
  1108. mpfr_float_backend(const gmp_float<D>& val)
  1109. : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(mpf_get_prec(val.data())) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(get_default_precision())))
  1110. {
  1111. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  1112. }
  1113. mpfr_float_backend(const gmp_int& val)
  1114. : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(used_gmp_int_bits(val)) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(thread_default_precision())))
  1115. {
  1116. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  1117. }
  1118. mpfr_float_backend(const gmp_rational& val)
  1119. : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? static_cast<unsigned>(used_gmp_rational_bits(val)) : static_cast<unsigned>(boost::multiprecision::detail::digits10_2_2(thread_default_precision())))
  1120. {
  1121. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  1122. }
  1123. mpfr_float_backend& operator=(const mpfr_float_backend& o) = default;
  1124. // rvalue assign
  1125. mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept = default;
  1126. template <class V>
  1127. typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<0, allocate_dynamic>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
  1128. {
  1129. constexpr unsigned d10 = std::is_floating_point<V>::value ?
  1130. std::numeric_limits<V>::digits10 :
  1131. std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 :
  1132. 1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits);
  1133. if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1134. {
  1135. BOOST_IF_CONSTEXPR(std::is_floating_point<V>::value)
  1136. {
  1137. if (std::numeric_limits<V>::digits > mpfr_get_prec(this->data()))
  1138. mpfr_set_prec(this->data(), std::numeric_limits<V>::digits);
  1139. }
  1140. else
  1141. {
  1142. if(precision() < d10)
  1143. this->precision(d10);
  1144. }
  1145. }
  1146. *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
  1147. return *this;
  1148. }
  1149. mpfr_float_backend& operator=(const mpfr_t val)
  1150. {
  1151. if (this->m_data[0]._mpfr_d == nullptr)
  1152. mpfr_init2(this->m_data, preserve_all_precision() ? static_cast<mpfr_prec_t>(mpfr_get_prec(val)) : static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision())));
  1153. else if(preserve_all_precision())
  1154. mpfr_set_prec(this->m_data, mpfr_get_prec(val));
  1155. mpfr_set(this->m_data, val, GMP_RNDN);
  1156. return *this;
  1157. }
  1158. mpfr_float_backend& operator=(const mpf_t val)
  1159. {
  1160. if (this->m_data[0]._mpfr_d == nullptr)
  1161. mpfr_init2(this->m_data, preserve_all_precision() ? static_cast<mpfr_prec_t>(mpf_get_prec(val)) : static_cast<mpfr_prec_t>(boost::multiprecision::detail::digits10_2_2(get_default_precision())));
  1162. else if(preserve_all_precision())
  1163. mpfr_set_prec(this->m_data, static_cast<mpfr_prec_t>(mpf_get_prec(val)));
  1164. mpfr_set_f(this->m_data, val, GMP_RNDN);
  1165. return *this;
  1166. }
  1167. mpfr_float_backend& operator=(const mpz_t val)
  1168. {
  1169. if (this->m_data[0]._mpfr_d == nullptr)
  1170. mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(get_default_precision())));
  1171. mpfr_set_z(this->m_data, val, GMP_RNDN);
  1172. return *this;
  1173. }
  1174. mpfr_float_backend& operator=(const mpq_t val)
  1175. {
  1176. if (this->m_data[0]._mpfr_d == nullptr)
  1177. mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(get_default_precision())));
  1178. mpfr_set_q(this->m_data, val, GMP_RNDN);
  1179. return *this;
  1180. }
  1181. template <unsigned D>
  1182. mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
  1183. {
  1184. if (this->m_data[0]._mpfr_d == nullptr)
  1185. mpfr_init2(this->m_data, preserve_related_precision() ? static_cast<mpfr_prec_t>(mpfr_get_prec(val.data())) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
  1186. else if (preserve_related_precision())
  1187. mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
  1188. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  1189. return *this;
  1190. }
  1191. template <unsigned D>
  1192. mpfr_float_backend& operator=(const gmp_float<D>& val)
  1193. {
  1194. if (this->m_data[0]._mpfr_d == nullptr)
  1195. mpfr_init2(this->m_data, preserve_all_precision() ? static_cast<mpfr_prec_t>(mpf_get_prec(val.data())) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
  1196. else if (preserve_all_precision())
  1197. mpfr_set_prec(this->m_data, static_cast<mpfr_prec_t>(mpf_get_prec(val.data())));
  1198. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  1199. return *this;
  1200. }
  1201. mpfr_float_backend& operator=(const gmp_int& val)
  1202. {
  1203. if (this->m_data[0]._mpfr_d == nullptr)
  1204. {
  1205. unsigned requested_precision = this->thread_default_precision();
  1206. if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1207. {
  1208. unsigned d2 = static_cast<unsigned>(used_gmp_int_bits(val));
  1209. unsigned d10 = static_cast<unsigned>(1ULL + multiprecision::detail::digits2_2_10(d2));
  1210. if (d10 > requested_precision)
  1211. requested_precision = d10;
  1212. }
  1213. mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(requested_precision)));
  1214. }
  1215. else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1216. {
  1217. unsigned requested_precision = this->thread_default_precision();
  1218. unsigned d2 = static_cast<unsigned>(used_gmp_int_bits(val));
  1219. unsigned d10 = static_cast<unsigned>(1ULL + multiprecision::detail::digits2_2_10(d2));
  1220. if (d10 > requested_precision)
  1221. this->precision(d10);
  1222. }
  1223. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  1224. return *this;
  1225. }
  1226. mpfr_float_backend& operator=(const gmp_rational& val)
  1227. {
  1228. if (this->m_data[0]._mpfr_d == nullptr)
  1229. {
  1230. unsigned requested_precision = this->get_default_precision();
  1231. if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1232. {
  1233. unsigned d10 = static_cast<unsigned>(1u + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)));
  1234. if (d10 > requested_precision)
  1235. requested_precision = d10;
  1236. }
  1237. mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(requested_precision)));
  1238. }
  1239. else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1240. {
  1241. unsigned requested_precision = this->get_default_precision();
  1242. unsigned d10 = static_cast<unsigned>(1u + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)));
  1243. if (d10 > requested_precision)
  1244. this->precision(d10);
  1245. }
  1246. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  1247. return *this;
  1248. }
  1249. static unsigned default_precision() noexcept
  1250. {
  1251. return get_global_default_precision();
  1252. }
  1253. static void default_precision(unsigned v) noexcept
  1254. {
  1255. get_global_default_precision() = v;
  1256. }
  1257. static unsigned thread_default_precision() noexcept
  1258. {
  1259. return get_default_precision();
  1260. }
  1261. static void thread_default_precision(unsigned v) noexcept
  1262. {
  1263. get_default_precision() = v;
  1264. }
  1265. unsigned precision() const noexcept
  1266. {
  1267. return static_cast<unsigned>(multiprecision::detail::digits2_2_10(static_cast<unsigned long>(mpfr_get_prec(this->m_data))));
  1268. }
  1269. void precision(unsigned digits10) noexcept
  1270. {
  1271. mpfr_prec_round(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2((digits10))), GMP_RNDN);
  1272. }
  1273. //
  1274. // Variable precision options:
  1275. //
  1276. static variable_precision_options default_variable_precision_options()noexcept
  1277. {
  1278. return get_global_default_options();
  1279. }
  1280. static variable_precision_options thread_default_variable_precision_options()noexcept
  1281. {
  1282. return get_default_options();
  1283. }
  1284. static void default_variable_precision_options(variable_precision_options opts)
  1285. {
  1286. get_global_default_options() = opts;
  1287. }
  1288. static void thread_default_variable_precision_options(variable_precision_options opts)
  1289. {
  1290. get_default_options() = opts;
  1291. }
  1292. static bool preserve_source_precision()
  1293. {
  1294. return get_default_options() >= variable_precision_options::preserve_source_precision;
  1295. }
  1296. static bool preserve_related_precision()
  1297. {
  1298. return get_default_options() >= variable_precision_options::preserve_related_precision;
  1299. }
  1300. static bool preserve_all_precision()
  1301. {
  1302. return get_default_options() >= variable_precision_options::preserve_all_precision;
  1303. }
  1304. };
  1305. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  1306. inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
  1307. {
  1308. return a.compare(b) == 0;
  1309. }
  1310. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  1311. inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
  1312. {
  1313. return a.compare(b) < 0;
  1314. }
  1315. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  1316. inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
  1317. {
  1318. return a.compare(b) > 0;
  1319. }
  1320. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1321. inline bool eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b)noexcept
  1322. {
  1323. return mpfr_equal_p(a.data(), b.data());
  1324. }
  1325. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1326. inline bool eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
  1327. {
  1328. return mpfr_less_p(a.data(), b.data());
  1329. }
  1330. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1331. inline bool eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
  1332. {
  1333. return mpfr_greater_p(a.data(), b.data());
  1334. }
  1335. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1336. inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  1337. {
  1338. mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
  1339. }
  1340. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1341. inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  1342. {
  1343. mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
  1344. }
  1345. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1346. inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  1347. {
  1348. if ((void*)&o == (void*)&result)
  1349. mpfr_sqr(result.data(), o.data(), GMP_RNDN);
  1350. else
  1351. mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
  1352. }
  1353. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1354. inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  1355. {
  1356. mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
  1357. }
  1358. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1359. inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  1360. {
  1361. mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
  1362. }
  1363. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1364. inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  1365. {
  1366. mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
  1367. }
  1368. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1369. inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  1370. {
  1371. mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
  1372. }
  1373. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1374. inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  1375. {
  1376. mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
  1377. }
  1378. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1379. inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
  1380. {
  1381. if (i > 0)
  1382. mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
  1383. else
  1384. mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
  1385. }
  1386. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1387. inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
  1388. {
  1389. if (i > 0)
  1390. mpfr_sub_ui(result.data(), result.data(), static_cast<typename std::make_unsigned<long>::type>(i), GMP_RNDN);
  1391. else
  1392. mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
  1393. }
  1394. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1395. inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
  1396. {
  1397. mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
  1398. if (i < 0)
  1399. mpfr_neg(result.data(), result.data(), GMP_RNDN);
  1400. }
  1401. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1402. inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
  1403. {
  1404. mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
  1405. if (i < 0)
  1406. mpfr_neg(result.data(), result.data(), GMP_RNDN);
  1407. }
  1408. //
  1409. // Specialised 3 arg versions of the basic operators:
  1410. //
  1411. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
  1412. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
  1413. {
  1414. mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
  1415. }
  1416. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1417. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1418. {
  1419. mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
  1420. }
  1421. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1422. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1423. {
  1424. if (y < 0)
  1425. mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
  1426. else
  1427. mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
  1428. }
  1429. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1430. inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1431. {
  1432. mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
  1433. }
  1434. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1435. inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1436. {
  1437. if (x < 0)
  1438. {
  1439. mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
  1440. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1441. }
  1442. else
  1443. mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
  1444. }
  1445. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
  1446. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
  1447. {
  1448. mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
  1449. }
  1450. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1451. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1452. {
  1453. mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
  1454. }
  1455. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1456. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1457. {
  1458. if (y < 0)
  1459. mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
  1460. else
  1461. mpfr_sub_ui(a.data(), x.data(), static_cast<typename std::make_unsigned<long>::type>(y), GMP_RNDN);
  1462. }
  1463. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1464. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1465. {
  1466. mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
  1467. }
  1468. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1469. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1470. {
  1471. if (x < 0)
  1472. {
  1473. mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
  1474. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1475. }
  1476. else
  1477. mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
  1478. }
  1479. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
  1480. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
  1481. {
  1482. if ((void*)&x == (void*)&y)
  1483. mpfr_sqr(a.data(), x.data(), GMP_RNDN);
  1484. else
  1485. mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
  1486. }
  1487. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1488. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1489. {
  1490. mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
  1491. }
  1492. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1493. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1494. {
  1495. if (y < 0)
  1496. {
  1497. mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
  1498. a.negate();
  1499. }
  1500. else
  1501. mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
  1502. }
  1503. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1504. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1505. {
  1506. mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
  1507. }
  1508. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1509. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1510. {
  1511. if (x < 0)
  1512. {
  1513. mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
  1514. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1515. }
  1516. else
  1517. mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
  1518. }
  1519. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
  1520. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
  1521. {
  1522. mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
  1523. }
  1524. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1525. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1526. {
  1527. mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
  1528. }
  1529. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1530. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1531. {
  1532. if (y < 0)
  1533. {
  1534. mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
  1535. a.negate();
  1536. }
  1537. else
  1538. mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
  1539. }
  1540. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1541. inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1542. {
  1543. mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
  1544. }
  1545. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1546. inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1547. {
  1548. if (x < 0)
  1549. {
  1550. mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
  1551. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1552. }
  1553. else
  1554. mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
  1555. }
  1556. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1557. inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1558. {
  1559. return 0 != mpfr_zero_p(val.data());
  1560. }
  1561. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1562. inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1563. {
  1564. return mpfr_sgn(val.data());
  1565. }
  1566. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1567. inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1568. {
  1569. if (mpfr_nan_p(val.data()))
  1570. {
  1571. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1572. }
  1573. *result = mpfr_get_ui(val.data(), GMP_RNDZ);
  1574. }
  1575. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1576. inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1577. {
  1578. if (mpfr_nan_p(val.data()))
  1579. {
  1580. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1581. }
  1582. *result = mpfr_get_si(val.data(), GMP_RNDZ);
  1583. }
  1584. #ifdef _MPFR_H_HAVE_INTMAX_T
  1585. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1586. inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1587. {
  1588. if (mpfr_nan_p(val.data()))
  1589. {
  1590. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1591. }
  1592. *result = mpfr_get_uj(val.data(), GMP_RNDZ);
  1593. }
  1594. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1595. inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1596. {
  1597. if (mpfr_nan_p(val.data()))
  1598. {
  1599. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1600. }
  1601. *result = mpfr_get_sj(val.data(), GMP_RNDZ);
  1602. }
  1603. #endif
  1604. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1605. inline void eval_convert_to(float* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1606. {
  1607. *result = mpfr_get_flt(val.data(), GMP_RNDN);
  1608. }
  1609. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1610. inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1611. {
  1612. *result = mpfr_get_d(val.data(), GMP_RNDN);
  1613. }
  1614. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1615. inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1616. {
  1617. *result = mpfr_get_ld(val.data(), GMP_RNDN);
  1618. }
  1619. #ifdef BOOST_HAS_INT128
  1620. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1621. inline void eval_convert_to(int128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1622. {
  1623. gmp_int i;
  1624. mpfr_get_z(i.data(), val.data(), GMP_RNDN);
  1625. eval_convert_to(result, i);
  1626. }
  1627. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1628. inline void eval_convert_to(uint128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1629. {
  1630. gmp_int i;
  1631. mpfr_get_z(i.data(), val.data(), GMP_RNDN);
  1632. eval_convert_to(result, i);
  1633. }
  1634. #endif
  1635. #if defined(BOOST_HAS_FLOAT128)
  1636. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1637. inline void eval_convert_to(float128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1638. {
  1639. *result = float128_procs::strtoflt128(val.str(0, std::ios_base::scientific).c_str(), nullptr);
  1640. }
  1641. #endif
  1642. //
  1643. // Native non-member operations:
  1644. //
  1645. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1646. inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1647. {
  1648. mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
  1649. }
  1650. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1651. inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1652. {
  1653. mpfr_abs(result.data(), val.data(), GMP_RNDN);
  1654. }
  1655. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1656. inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1657. {
  1658. mpfr_abs(result.data(), val.data(), GMP_RNDN);
  1659. }
  1660. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1661. inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1662. {
  1663. mpfr_ceil(result.data(), val.data());
  1664. }
  1665. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1666. inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1667. {
  1668. mpfr_floor(result.data(), val.data());
  1669. }
  1670. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1671. inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1672. {
  1673. mpfr_trunc(result.data(), val.data());
  1674. }
  1675. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1676. inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
  1677. {
  1678. using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
  1679. if (e > 0)
  1680. mpfr_mul_2exp(result.data(), val.data(), static_cast<local_uint_type>(e), GMP_RNDN);
  1681. else if (e < 0)
  1682. mpfr_div_2exp(result.data(), val.data(), static_cast<local_uint_type>(-e), GMP_RNDN);
  1683. else
  1684. result = val;
  1685. }
  1686. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1687. inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
  1688. {
  1689. if (mpfr_zero_p(val.data()))
  1690. {
  1691. *e = 0;
  1692. result = val;
  1693. return;
  1694. }
  1695. mp_exp_t v = mpfr_get_exp(val.data());
  1696. *e = static_cast<int>(v);
  1697. if (v)
  1698. eval_ldexp(result, val, -v);
  1699. else
  1700. result = val;
  1701. }
  1702. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1703. inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
  1704. {
  1705. if (mpfr_zero_p(val.data()))
  1706. {
  1707. *e = 0;
  1708. result = val;
  1709. return;
  1710. }
  1711. mp_exp_t v = mpfr_get_exp(val.data());
  1712. *e = v;
  1713. if(v)
  1714. eval_ldexp(result, val, -v);
  1715. else
  1716. result = val;
  1717. }
  1718. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1719. inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) noexcept
  1720. {
  1721. return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
  1722. }
  1723. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1724. inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
  1725. {
  1726. if (mpfr_zero_p(b.data()) && mpfr_integer_p(e.data()) && (mpfr_signbit(e.data()) == 0) && mpfr_fits_ulong_p(e.data(), GMP_RNDN) && (mpfr_get_ui(e.data(), GMP_RNDN) & 1))
  1727. {
  1728. mpfr_set(result.data(), b.data(), GMP_RNDN);
  1729. }
  1730. else
  1731. mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
  1732. }
  1733. #ifdef BOOST_MSVC
  1734. //
  1735. // The enable_if usage below doesn't work with msvc - but only when
  1736. // certain other enable_if usages are defined first. It's a capricious
  1737. // and rather annoying compiler bug in other words....
  1738. //
  1739. #define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10)&&
  1740. #else
  1741. #define BOOST_MP_ENABLE_IF_WORKAROUND
  1742. #endif
  1743. template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
  1744. inline typename std::enable_if<boost::multiprecision::detail::is_signed<Integer>::value && boost::multiprecision::detail::is_integral<Integer>::value && (BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long)))>::type
  1745. eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
  1746. {
  1747. mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
  1748. }
  1749. template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
  1750. inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value && (BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long)))>::type
  1751. eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
  1752. {
  1753. mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
  1754. }
  1755. #undef BOOST_MP_ENABLE_IF_WORKAROUND
  1756. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1757. inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1758. {
  1759. mpfr_exp(result.data(), arg.data(), GMP_RNDN);
  1760. }
  1761. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1762. inline void eval_exp2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1763. {
  1764. mpfr_exp2(result.data(), arg.data(), GMP_RNDN);
  1765. }
  1766. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1767. inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1768. {
  1769. mpfr_log(result.data(), arg.data(), GMP_RNDN);
  1770. }
  1771. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1772. inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1773. {
  1774. mpfr_log10(result.data(), arg.data(), GMP_RNDN);
  1775. }
  1776. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1777. inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1778. {
  1779. mpfr_sin(result.data(), arg.data(), GMP_RNDN);
  1780. }
  1781. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1782. inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1783. {
  1784. mpfr_cos(result.data(), arg.data(), GMP_RNDN);
  1785. }
  1786. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1787. inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1788. {
  1789. mpfr_tan(result.data(), arg.data(), GMP_RNDN);
  1790. }
  1791. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1792. inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1793. {
  1794. mpfr_asin(result.data(), arg.data(), GMP_RNDN);
  1795. }
  1796. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1797. inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1798. {
  1799. mpfr_acos(result.data(), arg.data(), GMP_RNDN);
  1800. }
  1801. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1802. inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1803. {
  1804. mpfr_atan(result.data(), arg.data(), GMP_RNDN);
  1805. }
  1806. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1807. inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
  1808. {
  1809. mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
  1810. }
  1811. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1812. inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1813. {
  1814. mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
  1815. }
  1816. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1817. inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1818. {
  1819. mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
  1820. }
  1821. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1822. inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1823. {
  1824. mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
  1825. }
  1826. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1827. inline void eval_log2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1828. {
  1829. mpfr_log2(result.data(), arg.data(), GMP_RNDN);
  1830. }
  1831. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1832. inline void eval_modf(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg, mpfr_float_backend<Digits10, AllocateType>* pipart)
  1833. {
  1834. if (pipart == nullptr)
  1835. {
  1836. mpfr_float_backend<Digits10, AllocateType> ipart;
  1837. mpfr_modf(ipart.data(), result.data(), arg.data(), GMP_RNDN);
  1838. }
  1839. else
  1840. {
  1841. mpfr_modf(pipart->data(), result.data(), arg.data(), GMP_RNDN);
  1842. }
  1843. }
  1844. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1845. inline void eval_remainder(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
  1846. {
  1847. mpfr_remainder(result.data(), a.data(), b.data(), GMP_RNDN);
  1848. }
  1849. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1850. inline void eval_remquo(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, int* pi)
  1851. {
  1852. long l;
  1853. mpfr_remquo(result.data(), &l, a.data(), b.data(), GMP_RNDN);
  1854. if (pi)
  1855. *pi = static_cast<int>(l);
  1856. }
  1857. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1858. inline void eval_fmod(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
  1859. {
  1860. mpfr_fmod(result.data(), a.data(), b.data(), GMP_RNDN);
  1861. }
  1862. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1863. inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
  1864. {
  1865. mpfr_fma(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
  1866. }
  1867. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1868. inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
  1869. {
  1870. mpfr_fma(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
  1871. }
  1872. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1873. inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
  1874. {
  1875. mpfr_fms(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
  1876. result.negate();
  1877. }
  1878. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1879. inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
  1880. {
  1881. mpfr_fms(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
  1882. }
  1883. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1884. inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const mpfr_float_backend<Digits10, AllocateType>& arg)
  1885. {
  1886. return (arg.data()[0]._mpfr_sign < 0) ? 1 : 0;
  1887. }
  1888. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1889. inline std::size_t hash_value(const mpfr_float_backend<Digits10, AllocateType>& val)
  1890. {
  1891. std::size_t result = 0;
  1892. std::size_t len = val.data()[0]._mpfr_prec / mp_bits_per_limb;
  1893. if (val.data()[0]._mpfr_prec % mp_bits_per_limb)
  1894. ++len;
  1895. for (std::size_t i = 0; i < len; ++i)
  1896. boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_d[i]);
  1897. boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_exp, val.data()[0]._mpfr_sign);
  1898. return result;
  1899. }
  1900. } // namespace backends
  1901. namespace detail {
  1902. template <>
  1903. struct is_variable_precision<backends::mpfr_float_backend<0> > : public std::integral_constant<bool, true>
  1904. {};
  1905. } // namespace detail
  1906. template <>
  1907. struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public std::integral_constant<int, number_kind_floating_point>
  1908. {};
  1909. template <unsigned D, boost::multiprecision::mpfr_allocation_type A1, boost::multiprecision::mpfr_allocation_type A2>
  1910. struct is_equivalent_number_type<backends::mpfr_float_backend<D, A1>, backends::mpfr_float_backend<D, A2> > : public std::integral_constant<bool, true> {};
  1911. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1912. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& b)
  1913. {
  1914. return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(-a) : a;
  1915. }
  1916. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1917. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& b)
  1918. {
  1919. return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>(-a) : a;
  1920. }
  1921. } // namespace multiprecision
  1922. namespace math {
  1923. using boost::multiprecision::copysign;
  1924. using boost::multiprecision::signbit;
  1925. namespace tools {
  1926. #ifndef BOOST_MP_MATH_AVAILABLE
  1927. template <typename T>
  1928. inline int digits();
  1929. template <typename T>
  1930. inline T max_value();
  1931. template <typename T>
  1932. inline T min_value();
  1933. #endif
  1934. inline void set_output_precision(const boost::multiprecision::mpfr_float& val, std::ostream& os)
  1935. {
  1936. os << std::setprecision(static_cast<int>(val.precision()));
  1937. }
  1938. template <>
  1939. inline int digits<boost::multiprecision::mpfr_float>()
  1940. #ifdef BOOST_MATH_NOEXCEPT
  1941. noexcept
  1942. #endif
  1943. {
  1944. return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision()));
  1945. }
  1946. template <>
  1947. inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
  1948. #ifdef BOOST_MATH_NOEXCEPT
  1949. noexcept
  1950. #endif
  1951. {
  1952. return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision()));
  1953. }
  1954. template <>
  1955. inline boost::multiprecision::mpfr_float
  1956. max_value<boost::multiprecision::mpfr_float>()
  1957. {
  1958. boost::multiprecision::mpfr_float result(0.5);
  1959. mpfr_mul_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(mpfr_get_emax()), GMP_RNDN);
  1960. BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
  1961. return result;
  1962. }
  1963. template <>
  1964. inline boost::multiprecision::mpfr_float
  1965. min_value<boost::multiprecision::mpfr_float>()
  1966. {
  1967. boost::multiprecision::mpfr_float result(0.5);
  1968. mpfr_div_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(-mpfr_get_emin()), GMP_RNDN);
  1969. BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
  1970. return result;
  1971. }
  1972. template <>
  1973. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
  1974. max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
  1975. {
  1976. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
  1977. mpfr_mul_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(mpfr_get_emax()), GMP_RNDN);
  1978. BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
  1979. return result;
  1980. }
  1981. template <>
  1982. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
  1983. min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
  1984. {
  1985. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
  1986. mpfr_div_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(-mpfr_get_emin()), GMP_RNDN);
  1987. BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
  1988. return result;
  1989. }
  1990. //
  1991. // Over again with debug_adaptor:
  1992. //
  1993. template <>
  1994. inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  1995. #ifdef BOOST_MATH_NOEXCEPT
  1996. noexcept
  1997. #endif
  1998. {
  1999. return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::thread_default_precision()));
  2000. }
  2001. template <>
  2002. inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2003. #ifdef BOOST_MATH_NOEXCEPT
  2004. noexcept
  2005. #endif
  2006. {
  2007. return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::thread_default_precision()));
  2008. }
  2009. template <>
  2010. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
  2011. max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2012. {
  2013. return max_value<boost::multiprecision::mpfr_float>().backend();
  2014. }
  2015. template <>
  2016. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
  2017. min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2018. {
  2019. return min_value<boost::multiprecision::mpfr_float>().backend();
  2020. }
  2021. template <>
  2022. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
  2023. max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2024. {
  2025. return max_value<boost::multiprecision::mpfr_float>().backend();
  2026. }
  2027. template <>
  2028. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
  2029. min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2030. {
  2031. return min_value<boost::multiprecision::mpfr_float>().backend();
  2032. }
  2033. //
  2034. // Over again with logged_adaptor:
  2035. //
  2036. template <>
  2037. inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2038. #ifdef BOOST_MATH_NOEXCEPT
  2039. noexcept
  2040. #endif
  2041. {
  2042. return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision()));
  2043. }
  2044. template <>
  2045. inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2046. #ifdef BOOST_MATH_NOEXCEPT
  2047. noexcept
  2048. #endif
  2049. {
  2050. return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision()));
  2051. }
  2052. template <>
  2053. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
  2054. max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2055. {
  2056. return max_value<boost::multiprecision::mpfr_float>().backend();
  2057. }
  2058. template <>
  2059. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
  2060. min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2061. {
  2062. return min_value<boost::multiprecision::mpfr_float>().backend();
  2063. }
  2064. template <>
  2065. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
  2066. max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2067. {
  2068. return max_value<boost::multiprecision::mpfr_float>().backend();
  2069. }
  2070. template <>
  2071. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
  2072. min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2073. {
  2074. return min_value<boost::multiprecision::mpfr_float>().backend();
  2075. }
  2076. } // namespace tools
  2077. namespace constants { namespace detail {
  2078. template <class T>
  2079. struct constant_pi;
  2080. template <class T>
  2081. struct constant_ln_two;
  2082. template <class T>
  2083. struct constant_euler;
  2084. template <class T>
  2085. struct constant_catalan;
  2086. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2087. struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  2088. {
  2089. using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  2090. template <int N>
  2091. static inline const result_type& get(const std::integral_constant<int, N>&)
  2092. {
  2093. // Rely on C++11 thread safe initialization:
  2094. static result_type result{get(std::integral_constant<int, 0>())};
  2095. return result;
  2096. }
  2097. static inline const result_type get(const std::integral_constant<int, 0>&)
  2098. {
  2099. result_type result;
  2100. mpfr_const_pi(result.backend().data(), GMP_RNDN);
  2101. return result;
  2102. }
  2103. };
  2104. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2105. struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  2106. {
  2107. using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  2108. template <int N>
  2109. static inline const result_type& get(const std::integral_constant<int, N>&)
  2110. {
  2111. // Rely on C++11 thread safe initialization:
  2112. static result_type result{get(std::integral_constant<int, 0>())};
  2113. return result;
  2114. }
  2115. static inline const result_type get(const std::integral_constant<int, 0>&)
  2116. {
  2117. result_type result;
  2118. mpfr_const_log2(result.backend().data(), GMP_RNDN);
  2119. return result;
  2120. }
  2121. };
  2122. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2123. struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  2124. {
  2125. using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  2126. template <int N>
  2127. static inline const result_type& get(const std::integral_constant<int, N>&)
  2128. {
  2129. // Rely on C++11 thread safe initialization:
  2130. static result_type result{get(std::integral_constant<int, 0>())};
  2131. return result;
  2132. }
  2133. static inline const result_type get(const std::integral_constant<int, 0>&)
  2134. {
  2135. result_type result;
  2136. mpfr_const_euler(result.backend().data(), GMP_RNDN);
  2137. return result;
  2138. }
  2139. };
  2140. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2141. struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  2142. {
  2143. using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  2144. template <int N>
  2145. static inline const result_type& get(const std::integral_constant<int, N>&)
  2146. {
  2147. // Rely on C++11 thread safe initialization:
  2148. static result_type result{get(std::integral_constant<int, 0>())};
  2149. return result;
  2150. }
  2151. static inline const result_type get(const std::integral_constant<int, 0>&)
  2152. {
  2153. result_type result;
  2154. mpfr_const_catalan(result.backend().data(), GMP_RNDN);
  2155. return result;
  2156. }
  2157. };
  2158. //
  2159. // Over again with debug_adaptor:
  2160. //
  2161. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2162. struct constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2163. {
  2164. using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2165. template <int N>
  2166. static inline const result_type& get(const std::integral_constant<int, N>&)
  2167. {
  2168. // Rely on C++11 thread safe initialization:
  2169. static result_type result{get(std::integral_constant<int, 0>())};
  2170. return result;
  2171. }
  2172. static inline const result_type get(const std::integral_constant<int, 0>&)
  2173. {
  2174. result_type result;
  2175. mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
  2176. result.backend().update_view();
  2177. return result;
  2178. }
  2179. };
  2180. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2181. struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2182. {
  2183. using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2184. template <int N>
  2185. static inline const result_type& get(const std::integral_constant<int, N>&)
  2186. {
  2187. // Rely on C++11 thread safe initialization:
  2188. static result_type result{get(std::integral_constant<int, 0>())};
  2189. return result;
  2190. }
  2191. static inline const result_type get(const std::integral_constant<int, 0>&)
  2192. {
  2193. result_type result;
  2194. mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
  2195. result.backend().update_view();
  2196. return result;
  2197. }
  2198. };
  2199. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2200. struct constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2201. {
  2202. using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2203. template <int N>
  2204. static inline const result_type& get(const std::integral_constant<int, N>&)
  2205. {
  2206. // Rely on C++11 thread safe initialization:
  2207. static result_type result{get(std::integral_constant<int, 0>())};
  2208. return result;
  2209. }
  2210. static inline const result_type get(const std::integral_constant<int, 0>&)
  2211. {
  2212. result_type result;
  2213. mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
  2214. result.backend().update_view();
  2215. return result;
  2216. }
  2217. };
  2218. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2219. struct constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2220. {
  2221. using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2222. template <int N>
  2223. static inline const result_type& get(const std::integral_constant<int, N>&)
  2224. {
  2225. // Rely on C++11 thread safe initialization:
  2226. static result_type result{get(std::integral_constant<int, 0>())};
  2227. return result;
  2228. }
  2229. static inline const result_type get(const std::integral_constant<int, 0>&)
  2230. {
  2231. result_type result;
  2232. mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
  2233. result.backend().update_view();
  2234. return result;
  2235. }
  2236. };
  2237. //
  2238. // Over again with logged_adaptor:
  2239. //
  2240. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2241. struct constant_pi<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2242. {
  2243. using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2244. template <int N>
  2245. static inline const result_type& get(const std::integral_constant<int, N>&)
  2246. {
  2247. // C++11 thread safe static initialization:
  2248. static result_type result{get(std::integral_constant<int, 0>())};
  2249. return result;
  2250. }
  2251. static inline const result_type get(const std::integral_constant<int, 0>&)
  2252. {
  2253. result_type result;
  2254. mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
  2255. return result;
  2256. }
  2257. };
  2258. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2259. struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2260. {
  2261. using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2262. template <int N>
  2263. static inline const result_type& get(const std::integral_constant<int, N>&)
  2264. {
  2265. // C++11 thread safe static initialization:
  2266. static result_type result{get(std::integral_constant<int, 0>())};
  2267. return result;
  2268. }
  2269. static inline const result_type get(const std::integral_constant<int, 0>&)
  2270. {
  2271. result_type result;
  2272. mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
  2273. return result;
  2274. }
  2275. };
  2276. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2277. struct constant_euler<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2278. {
  2279. using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2280. template <int N>
  2281. static inline const result_type& get(const std::integral_constant<int, N>&)
  2282. {
  2283. // C++11 thread safe static initialization:
  2284. static result_type result{get(std::integral_constant<int, 0>())};
  2285. return result;
  2286. }
  2287. static inline const result_type get(const std::integral_constant<int, 0>&)
  2288. {
  2289. result_type result;
  2290. mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
  2291. return result;
  2292. }
  2293. };
  2294. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2295. struct constant_catalan<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2296. {
  2297. using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2298. template <int N>
  2299. static inline const result_type& get(const std::integral_constant<int, N>&)
  2300. {
  2301. // C++11 thread safe static initialization:
  2302. static result_type result{get(std::integral_constant<int, 0>())};
  2303. return result;
  2304. }
  2305. static inline const result_type get(const std::integral_constant<int, 0>&)
  2306. {
  2307. result_type result;
  2308. mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
  2309. return result;
  2310. }
  2311. };
  2312. }} // namespace constants::detail
  2313. } // namespace math
  2314. namespace multiprecision {
  2315. //
  2316. // Overloaded special functions which call native mpfr routines:
  2317. //
  2318. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2319. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2320. {
  2321. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2322. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2323. mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2324. return result;
  2325. }
  2326. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2327. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2328. {
  2329. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2330. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2331. mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2332. return result;
  2333. }
  2334. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2335. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2336. {
  2337. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2338. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2339. mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2340. return result;
  2341. }
  2342. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2343. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2344. {
  2345. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2346. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2347. mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2348. return result;
  2349. }
  2350. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2351. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2352. {
  2353. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2354. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2355. mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2356. return result;
  2357. }
  2358. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2359. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2360. {
  2361. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2362. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2363. mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2364. return result;
  2365. }
  2366. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2367. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2368. {
  2369. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2370. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2371. mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2372. return result;
  2373. }
  2374. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2375. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2376. {
  2377. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2378. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2379. mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2380. return result;
  2381. }
  2382. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2383. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2384. {
  2385. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2386. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2387. mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2388. return result;
  2389. }
  2390. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2391. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2392. {
  2393. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2394. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2395. mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2396. return result;
  2397. }
  2398. //
  2399. // Over again with debug_adaptor:
  2400. //
  2401. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2402. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2403. {
  2404. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2405. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2406. mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2407. result.backend().update_view();
  2408. return result;
  2409. }
  2410. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2411. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2412. {
  2413. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2414. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2415. mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2416. result.backend().update_view();
  2417. return result;
  2418. }
  2419. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2420. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2421. {
  2422. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2423. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2424. mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2425. result.backend().update_view();
  2426. return result;
  2427. }
  2428. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2429. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2430. {
  2431. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2432. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2433. mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2434. result.backend().update_view();
  2435. return result;
  2436. }
  2437. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2438. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2439. {
  2440. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2441. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2442. mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2443. result.backend().update_view();
  2444. return result;
  2445. }
  2446. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2447. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2448. {
  2449. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2450. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2451. mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2452. result.backend().update_view();
  2453. return result;
  2454. }
  2455. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2456. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2457. {
  2458. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2459. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2460. mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2461. result.backend().update_view();
  2462. return result;
  2463. }
  2464. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2465. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2466. {
  2467. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2468. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2469. mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2470. result.backend().update_view();
  2471. return result;
  2472. }
  2473. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2474. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2475. {
  2476. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2477. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2478. mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2479. result.backend().update_view();
  2480. return result;
  2481. }
  2482. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2483. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2484. {
  2485. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2486. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2487. mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2488. result.backend().update_view();
  2489. return result;
  2490. }
  2491. //
  2492. // Over again with logged_adaptor:
  2493. //
  2494. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2495. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2496. {
  2497. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2498. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2499. mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2500. return result;
  2501. }
  2502. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2503. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2504. {
  2505. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2506. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2507. mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2508. return result;
  2509. }
  2510. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2511. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2512. {
  2513. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2514. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2515. mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2516. return result;
  2517. }
  2518. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2519. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2520. {
  2521. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2522. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2523. mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2524. return result;
  2525. }
  2526. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2527. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2528. {
  2529. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2530. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2531. mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2532. return result;
  2533. }
  2534. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2535. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2536. {
  2537. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2538. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2539. mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2540. return result;
  2541. }
  2542. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2543. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2544. {
  2545. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2546. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2547. mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2548. return result;
  2549. }
  2550. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2551. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2552. {
  2553. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2554. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2555. mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2556. return result;
  2557. }
  2558. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2559. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2560. {
  2561. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2562. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2563. mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2564. return result;
  2565. }
  2566. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2567. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2568. {
  2569. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2570. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2571. mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2572. return result;
  2573. }
  2574. } // namespace multiprecision
  2575. namespace math {
  2576. //
  2577. // Overloaded special functions which call native mpfr routines:
  2578. //
  2579. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2580. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
  2581. {
  2582. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2583. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2584. mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2585. if (mpfr_inf_p(result.backend().data()))
  2586. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("asinh<%1%>(%1%)", nullptr, Policy());
  2587. if (mpfr_nan_p(result.backend().data()))
  2588. return policies::raise_evaluation_error("asinh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
  2589. return result;
  2590. }
  2591. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2592. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2593. {
  2594. return asinh(arg, policies::policy<>());
  2595. }
  2596. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2597. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
  2598. {
  2599. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2600. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2601. mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2602. if (mpfr_inf_p(result.backend().data()))
  2603. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("acosh<%1%>(%1%)", nullptr, Policy());
  2604. if (mpfr_nan_p(result.backend().data()))
  2605. return policies::raise_evaluation_error("acosh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
  2606. return result;
  2607. }
  2608. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2609. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2610. {
  2611. return acosh(arg, policies::policy<>());
  2612. }
  2613. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2614. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& )
  2615. {
  2616. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2617. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2618. mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2619. if (mpfr_inf_p(result.backend().data()))
  2620. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("atanh<%1%>(%1%)", nullptr, Policy());
  2621. if (mpfr_nan_p(result.backend().data()))
  2622. return policies::raise_evaluation_error("atanh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
  2623. return result;
  2624. }
  2625. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2626. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2627. {
  2628. return atanh(arg, policies::policy<>());
  2629. }
  2630. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2631. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
  2632. {
  2633. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2634. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2635. if (mpfr_nan_p(arg.backend().data()))
  2636. return policies::raise_domain_error("cbrt<%1%>(%1%)", "Input is a NaN", result, Policy());
  2637. mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2638. if (mpfr_inf_p(result.backend().data()))
  2639. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("cbrt<%1%>(%1%)", nullptr, Policy());
  2640. if (mpfr_nan_p(result.backend().data()))
  2641. return policies::raise_evaluation_error("cbrt<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
  2642. return result;
  2643. }
  2644. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2645. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2646. {
  2647. return cbrt(arg, policies::policy<>());
  2648. }
  2649. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2650. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
  2651. {
  2652. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2653. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2654. if (mpfr_nan_p(arg.backend().data()))
  2655. return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
  2656. mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2657. if (mpfr_inf_p(result.backend().data()))
  2658. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erf<%1%>(%1%)", nullptr, pol);
  2659. if (mpfr_nan_p(result.backend().data()))
  2660. return policies::raise_evaluation_error("erf<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2661. return result;
  2662. }
  2663. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2664. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2665. {
  2666. return erf(arg, policies::policy<>());
  2667. }
  2668. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2669. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
  2670. {
  2671. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2672. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2673. if (mpfr_nan_p(arg.backend().data()))
  2674. return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
  2675. mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2676. if (mpfr_inf_p(result.backend().data()))
  2677. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erfc<%1%>(%1%)", nullptr, pol);
  2678. if (mpfr_nan_p(result.backend().data()))
  2679. return policies::raise_evaluation_error("erfc<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2680. return result;
  2681. }
  2682. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2683. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2684. {
  2685. return erfc(arg, policies::policy<>());
  2686. }
  2687. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2688. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
  2689. {
  2690. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2691. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2692. if (mpfr_nan_p(arg.backend().data()))
  2693. return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
  2694. mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2695. if (mpfr_inf_p(result.backend().data()))
  2696. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("expm1<%1%>(%1%)", nullptr, pol);
  2697. if (mpfr_nan_p(result.backend().data()))
  2698. return policies::raise_evaluation_error("expm1<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2699. return result;
  2700. }
  2701. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2702. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2703. {
  2704. return expm1(arg, policies::policy<>());
  2705. }
  2706. #ifdef BOOST_MP_MATH_AVAILABLE
  2707. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2708. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> arg, int* sign, const Policy& pol)
  2709. {
  2710. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2711. (void)precision_guard; // warning suppression
  2712. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2713. if (arg > 0)
  2714. {
  2715. mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2716. if (sign)
  2717. *sign = 1;
  2718. }
  2719. else
  2720. {
  2721. if (floor(arg) == arg)
  2722. return policies::raise_pole_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >(
  2723. "lgamma<%1%>", "Evaluation of lgamma at a negative integer %1%.", arg, pol);
  2724. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> t = detail::sinpx(arg);
  2725. arg = -arg;
  2726. if (t < 0)
  2727. {
  2728. t = -t;
  2729. }
  2730. result = boost::multiprecision::log(boost::math::constants::pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >()) - lgamma(arg, 0, pol) - boost::multiprecision::log(t);
  2731. if (sign)
  2732. {
  2733. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> phase = 1 - arg;
  2734. phase = floor(phase) / 2;
  2735. if (floor(phase) == phase)
  2736. *sign = -1;
  2737. else
  2738. *sign = 1;
  2739. }
  2740. }
  2741. if (mpfr_inf_p(result.backend().data()))
  2742. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("lgamma<%1%>(%1%)", nullptr, pol);
  2743. if (mpfr_nan_p(result.backend().data()))
  2744. return policies::raise_evaluation_error("lgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2745. return result;
  2746. }
  2747. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2748. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, int* sign)
  2749. {
  2750. return lgamma(arg, sign, policies::policy<>());
  2751. }
  2752. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2753. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
  2754. {
  2755. return lgamma(arg, 0, pol);
  2756. }
  2757. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2758. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2759. {
  2760. return lgamma(arg, 0, policies::policy<>());
  2761. }
  2762. #endif // BOOST_MP_MATH_AVAILABLE
  2763. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2764. inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
  2765. {
  2766. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2767. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2768. mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2769. if (mpfr_inf_p(result.backend().data()))
  2770. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("tgamma<%1%>(%1%)", nullptr, pol);
  2771. if (mpfr_nan_p(result.backend().data()))
  2772. return policies::raise_evaluation_error("tgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2773. return result;
  2774. }
  2775. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2776. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2777. {
  2778. return tgamma(arg, policies::policy<>());
  2779. }
  2780. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2781. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
  2782. {
  2783. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2784. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2785. if (arg < -1)
  2786. return policies::raise_domain_error("log1p<%1%>(%1%)", "Argument was %1% but must be greater than -1", arg, pol);
  2787. mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2788. if (mpfr_inf_p(result.backend().data()))
  2789. return (arg == -1 ? -1 : 1) * policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("log1p<%1%>(%1%)", nullptr, pol);
  2790. if (mpfr_nan_p(result.backend().data()))
  2791. return policies::raise_evaluation_error("log1p<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2792. return result;
  2793. }
  2794. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2795. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2796. {
  2797. return log1p(arg, policies::policy<>());
  2798. }
  2799. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2800. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
  2801. {
  2802. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2803. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2804. mpfr_rec_sqrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2805. if (mpfr_inf_p(result.backend().data()))
  2806. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("rsqrt<%1%>(%1%)", nullptr, pol);
  2807. if (mpfr_nan_p(result.backend().data()))
  2808. return policies::raise_evaluation_error("rsqrt<%1%>(%1%)", "Negative argument, result is a NaN", result, pol);
  2809. return result;
  2810. }
  2811. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2812. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
  2813. {
  2814. return rsqrt(arg, policies::policy<>());
  2815. }
  2816. //
  2817. // Over again with debug_adaptor:
  2818. //
  2819. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2820. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2821. {
  2822. return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2823. }
  2824. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2825. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2826. {
  2827. return asinh(arg, policies::policy<>());
  2828. }
  2829. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2830. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2831. {
  2832. return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2833. }
  2834. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2835. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2836. {
  2837. return acosh(arg, policies::policy<>());
  2838. }
  2839. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2840. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2841. {
  2842. return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2843. }
  2844. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2845. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2846. {
  2847. return atanh(arg, policies::policy<>());
  2848. }
  2849. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2850. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2851. {
  2852. return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2853. }
  2854. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2855. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2856. {
  2857. return cbrt(arg, policies::policy<>());
  2858. }
  2859. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2860. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2861. {
  2862. return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2863. }
  2864. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2865. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2866. {
  2867. return erf(arg, policies::policy<>());
  2868. }
  2869. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2870. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2871. {
  2872. return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2873. }
  2874. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2875. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2876. {
  2877. return erfc(arg, policies::policy<>());
  2878. }
  2879. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2880. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2881. {
  2882. return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2883. }
  2884. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2885. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2886. {
  2887. return expm1(arg, policies::policy<>());
  2888. }
  2889. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2890. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> arg, int* sign, const Policy& pol)
  2891. {
  2892. return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
  2893. }
  2894. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2895. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, int* sign)
  2896. {
  2897. return lgamma(arg, sign, policies::policy<>());
  2898. }
  2899. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2900. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2901. {
  2902. return lgamma(arg, 0, pol);
  2903. }
  2904. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2905. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2906. {
  2907. return lgamma(arg, 0, policies::policy<>());
  2908. }
  2909. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2910. inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2911. {
  2912. return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2913. }
  2914. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2915. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2916. {
  2917. return tgamma(arg, policies::policy<>());
  2918. }
  2919. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2920. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2921. {
  2922. return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2923. }
  2924. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2925. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2926. {
  2927. return log1p(arg, policies::policy<>());
  2928. }
  2929. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2930. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2931. {
  2932. return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2933. }
  2934. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2935. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2936. {
  2937. return rsqrt(arg, policies::policy<>());
  2938. }
  2939. //
  2940. // Over again with logged_adaptor:
  2941. //
  2942. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2943. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2944. {
  2945. return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2946. }
  2947. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2948. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2949. {
  2950. return asinh(arg, policies::policy<>());
  2951. }
  2952. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2953. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2954. {
  2955. return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2956. }
  2957. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2958. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2959. {
  2960. return acosh(arg, policies::policy<>());
  2961. }
  2962. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2963. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2964. {
  2965. return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2966. }
  2967. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2968. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2969. {
  2970. return atanh(arg, policies::policy<>());
  2971. }
  2972. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2973. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2974. {
  2975. return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2976. }
  2977. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2978. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2979. {
  2980. return cbrt(arg, policies::policy<>());
  2981. }
  2982. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2983. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2984. {
  2985. return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2986. }
  2987. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2988. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2989. {
  2990. return erf(arg, policies::policy<>());
  2991. }
  2992. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2993. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  2994. {
  2995. return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2996. }
  2997. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2998. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  2999. {
  3000. return erfc(arg, policies::policy<>());
  3001. }
  3002. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3003. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  3004. {
  3005. return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  3006. }
  3007. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3008. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  3009. {
  3010. return expm1(arg, policies::policy<>());
  3011. }
  3012. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3013. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> arg, int* sign, const Policy& pol)
  3014. {
  3015. return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
  3016. }
  3017. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3018. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, int* sign)
  3019. {
  3020. return lgamma(arg, sign, policies::policy<>());
  3021. }
  3022. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3023. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  3024. {
  3025. return lgamma(arg, 0, pol);
  3026. }
  3027. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3028. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  3029. {
  3030. return lgamma(arg, 0, policies::policy<>());
  3031. }
  3032. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3033. inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  3034. {
  3035. return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  3036. }
  3037. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3038. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  3039. {
  3040. return tgamma(arg, policies::policy<>());
  3041. }
  3042. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3043. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  3044. {
  3045. return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  3046. }
  3047. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3048. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  3049. {
  3050. return log1p(arg, policies::policy<>());
  3051. }
  3052. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3053. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
  3054. {
  3055. return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  3056. }
  3057. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3058. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
  3059. {
  3060. return rsqrt(arg, policies::policy<>());
  3061. }
  3062. } // namespace math
  3063. } // namespace boost
  3064. namespace Eigen
  3065. {
  3066. template <class B1, class B2>
  3067. struct NumTraitsImp;
  3068. template <boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3069. struct NumTraitsImp<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>
  3070. {
  3071. using self_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>;
  3072. using Real = typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type;
  3073. using NonInteger = self_type; // Not correct but we can't do much better??
  3074. using Literal = double;
  3075. using Nested = self_type;
  3076. enum
  3077. {
  3078. IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
  3079. IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
  3080. ReadCost = 1,
  3081. AddCost = 4,
  3082. MulCost = 8,
  3083. IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
  3084. RequireInitialization = 1,
  3085. };
  3086. static Real epsilon()
  3087. {
  3088. #ifdef BOOST_MP_MATH_AVAILABLE
  3089. return boost::math::tools::epsilon< boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
  3090. #else
  3091. self_type result{1};
  3092. mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<self_type>::digits - 1, GMP_RNDN);
  3093. return result;
  3094. #endif
  3095. }
  3096. static Real dummy_precision()
  3097. {
  3098. return 1000 * epsilon();
  3099. }
  3100. static Real highest()
  3101. {
  3102. #ifdef BOOST_MP_MATH_AVAILABLE
  3103. return boost::math::tools::max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
  3104. #else
  3105. self_type value(0.5);
  3106. mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
  3107. return value;
  3108. #endif
  3109. }
  3110. static Real lowest()
  3111. {
  3112. #ifdef BOOST_MP_MATH_AVAILABLE
  3113. return boost::math::tools::min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
  3114. #else
  3115. return -(highest)();
  3116. #endif
  3117. }
  3118. static int digits10()
  3119. {
  3120. return Real::thread_default_precision();
  3121. }
  3122. static int digits()
  3123. {
  3124. return boost::math::tools::digits<Real>();
  3125. }
  3126. static int min_exponent()
  3127. {
  3128. return static_cast<int>(mpfr_get_emin());
  3129. }
  3130. static int max_exponent()
  3131. {
  3132. return static_cast<int>(mpfr_get_emax());
  3133. }
  3134. static Real infinity()
  3135. {
  3136. return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::infinity();
  3137. }
  3138. static Real quiet_NaN()
  3139. {
  3140. return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::quiet_NaN();
  3141. }
  3142. };
  3143. }
  3144. namespace std {
  3145. //
  3146. // numeric_limits [partial] specializations for the types declared in this header:
  3147. //
  3148. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3149. class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  3150. {
  3151. using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  3152. static number_type get_min()
  3153. {
  3154. number_type result{0.5};
  3155. mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
  3156. return result;
  3157. }
  3158. static number_type get_max()
  3159. {
  3160. number_type result{0.5};
  3161. mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
  3162. return result;
  3163. }
  3164. static number_type get_eps()
  3165. {
  3166. number_type result{1};
  3167. mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
  3168. return result;
  3169. }
  3170. public:
  3171. static constexpr bool is_specialized = true;
  3172. static number_type(min)()
  3173. {
  3174. static number_type value{get_min()};
  3175. return value;
  3176. }
  3177. static number_type(max)()
  3178. {
  3179. static number_type value{get_max()};
  3180. return value;
  3181. }
  3182. static constexpr number_type lowest()
  3183. {
  3184. return -(max)();
  3185. }
  3186. static constexpr int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
  3187. static constexpr int digits10 = Digits10;
  3188. // Is this really correct???
  3189. static constexpr int max_digits10 = static_cast<int>(boost::multiprecision::detail::calc_max_digits10<static_cast<unsigned>(digits)>::value);
  3190. static constexpr bool is_signed = true;
  3191. static constexpr bool is_integer = false;
  3192. static constexpr bool is_exact = false;
  3193. static constexpr int radix = 2;
  3194. static number_type epsilon()
  3195. {
  3196. static number_type value{get_eps()};
  3197. return value;
  3198. }
  3199. // What value should this be????
  3200. static number_type round_error()
  3201. {
  3202. // returns epsilon/2
  3203. return 0.5;
  3204. }
  3205. static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
  3206. static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
  3207. static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
  3208. static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
  3209. static constexpr bool has_infinity = true;
  3210. static constexpr bool has_quiet_NaN = true;
  3211. static constexpr bool has_signaling_NaN = false;
  3212. #ifdef _MSC_VER
  3213. #pragma warning(push)
  3214. #pragma warning(disable : 4996)
  3215. #endif
  3216. static constexpr float_denorm_style has_denorm = denorm_absent;
  3217. #ifdef _MSC_VER
  3218. #pragma warning(pop)
  3219. #endif
  3220. static constexpr bool has_denorm_loss = false;
  3221. static number_type infinity()
  3222. {
  3223. number_type value;
  3224. mpfr_set_inf(value.backend().data(), 1);
  3225. return value;
  3226. }
  3227. static number_type quiet_NaN()
  3228. {
  3229. number_type value;
  3230. mpfr_set_nan(value.backend().data());
  3231. return value;
  3232. }
  3233. static constexpr number_type signaling_NaN()
  3234. {
  3235. return number_type(0);
  3236. }
  3237. static constexpr number_type denorm_min() { return (min)(); }
  3238. static constexpr bool is_iec559 = false;
  3239. static constexpr bool is_bounded = true;
  3240. static constexpr bool is_modulo = false;
  3241. static constexpr bool traps = true;
  3242. static constexpr bool tinyness_before = false;
  3243. static constexpr float_round_style round_style = round_to_nearest;
  3244. };
  3245. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3246. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
  3247. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3248. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
  3249. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3250. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
  3251. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3252. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
  3253. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3254. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
  3255. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3256. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
  3257. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3258. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
  3259. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3260. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
  3261. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3262. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
  3263. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3264. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
  3265. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3266. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
  3267. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3268. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
  3269. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3270. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
  3271. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3272. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
  3273. #ifdef _MSC_VER
  3274. #pragma warning(push)
  3275. #pragma warning(disable : 4996)
  3276. #endif
  3277. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3278. constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
  3279. #ifdef _MSC_VER
  3280. #pragma warning(pop)
  3281. #endif
  3282. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3283. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
  3284. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3285. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
  3286. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3287. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
  3288. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3289. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
  3290. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3291. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
  3292. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3293. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
  3294. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3295. constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
  3296. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3297. class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
  3298. {
  3299. using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates>;
  3300. public:
  3301. static constexpr bool is_specialized = false;
  3302. static number_type(min)()
  3303. {
  3304. number_type value(0.5);
  3305. mpfr_div_2exp(value.backend().data(), value.backend().data(), -mpfr_get_emin(), GMP_RNDN);
  3306. return value;
  3307. }
  3308. static number_type(max)()
  3309. {
  3310. number_type value(0.5);
  3311. mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
  3312. return value;
  3313. }
  3314. static number_type lowest()
  3315. {
  3316. return -(max)();
  3317. }
  3318. static constexpr int digits = INT_MAX;
  3319. static constexpr int digits10 = INT_MAX;
  3320. static constexpr int max_digits10 = INT_MAX;
  3321. static constexpr bool is_signed = true;
  3322. static constexpr bool is_integer = false;
  3323. static constexpr bool is_exact = false;
  3324. static constexpr int radix = 2;
  3325. static number_type epsilon()
  3326. {
  3327. number_type value(1);
  3328. mpfr_div_2exp(value.backend().data(), value.backend().data(), boost::multiprecision::detail::digits10_2_2(number_type::thread_default_precision()) - 1, GMP_RNDN);
  3329. return value;
  3330. }
  3331. static number_type round_error()
  3332. {
  3333. return 0.5;
  3334. }
  3335. static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
  3336. static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
  3337. static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
  3338. static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
  3339. static constexpr bool has_infinity = true;
  3340. static constexpr bool has_quiet_NaN = true;
  3341. static constexpr bool has_signaling_NaN = false;
  3342. #ifdef _MSC_VER
  3343. #pragma warning(push)
  3344. #pragma warning(disable : 4996)
  3345. #endif
  3346. static constexpr float_denorm_style has_denorm = denorm_absent;
  3347. #ifdef _MSC_VER
  3348. #pragma warning(pop)
  3349. #endif
  3350. static constexpr bool has_denorm_loss = false;
  3351. static number_type infinity()
  3352. {
  3353. number_type value;
  3354. mpfr_set_inf(value.backend().data(), 1);
  3355. return value;
  3356. }
  3357. static number_type quiet_NaN()
  3358. {
  3359. number_type value;
  3360. mpfr_set_nan(value.backend().data());
  3361. return value;
  3362. }
  3363. static number_type signaling_NaN() { return number_type(0); }
  3364. static number_type denorm_min() { return (min)(); }
  3365. static constexpr bool is_iec559 = false;
  3366. static constexpr bool is_bounded = true;
  3367. static constexpr bool is_modulo = false;
  3368. static constexpr bool traps = false;
  3369. static constexpr bool tinyness_before = false;
  3370. static constexpr float_round_style round_style = round_toward_zero;
  3371. };
  3372. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3373. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
  3374. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3375. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
  3376. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3377. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
  3378. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3379. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
  3380. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3381. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
  3382. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3383. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
  3384. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3385. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
  3386. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3387. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
  3388. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3389. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
  3390. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3391. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
  3392. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3393. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
  3394. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3395. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
  3396. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3397. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
  3398. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3399. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
  3400. #ifdef _MSC_VER
  3401. #pragma warning(push)
  3402. #pragma warning(disable : 4996)
  3403. #endif
  3404. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3405. constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
  3406. #ifdef _MSC_VER
  3407. #pragma warning(pop)
  3408. #endif
  3409. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3410. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
  3411. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3412. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
  3413. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3414. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
  3415. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3416. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
  3417. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3418. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
  3419. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3420. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
  3421. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3422. constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;
  3423. } // namespace std
  3424. #endif