mpfr.hpp 201 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644
  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. }
  814. if (round_up)
  815. {
  816. ++e;
  817. ps[offset] = '1';
  818. ps[offset + 1] = 0;
  819. }
  820. else
  821. {
  822. ps[offset] = '0';
  823. ps[offset + 1] = 0;
  824. }
  825. }
  826. else
  827. {
  828. ps[offset] = '0';
  829. ps[offset + 1] = 0;
  830. }
  831. }
  832. else if (digits > 0)
  833. {
  834. ps = mpfr_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
  835. --e; // To match with what our formatter expects.
  836. }
  837. else
  838. {
  839. ps = mpfr_get_str(nullptr, &e, 10, 1, m_data, GMP_RNDN);
  840. --e;
  841. unsigned offset = *ps == '-' ? 1 : 0;
  842. ps[offset] = '0';
  843. ps[offset + 1] = 0;
  844. }
  845. }
  846. result = ps ? ps : "0";
  847. if (ps)
  848. mpfr_free_str(ps);
  849. }
  850. boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
  851. return result;
  852. }
  853. void negate() noexcept
  854. {
  855. mpfr_neg(m_data, m_data, GMP_RNDN);
  856. }
  857. template <mpfr_allocation_type AllocationType>
  858. int compare(const mpfr_float_backend<digits10, AllocationType>& o) const
  859. {
  860. return mpfr_cmp(m_data, o.m_data);
  861. }
  862. int compare(long i) const
  863. {
  864. return mpfr_cmp_si(m_data, i);
  865. }
  866. int compare(unsigned long i) const
  867. {
  868. return mpfr_cmp_ui(m_data, i);
  869. }
  870. int compare(double i) const
  871. {
  872. return mpfr_cmp_d(m_data, i);
  873. }
  874. int compare(long double i) const
  875. {
  876. return mpfr_cmp_ld(m_data, i);
  877. }
  878. template <class V>
  879. int compare(V v) const
  880. {
  881. mpfr_float_backend<digits10, allocate_stack> d;
  882. d = v;
  883. return compare(d);
  884. }
  885. mpfr_t& data() noexcept
  886. {
  887. return m_data;
  888. }
  889. const mpfr_t& data() const noexcept
  890. {
  891. return m_data;
  892. }
  893. protected:
  894. mpfr_t m_data;
  895. mp_limb_t m_buffer[limb_count];
  896. };
  897. #ifdef BOOST_MSVC
  898. #pragma warning(pop)
  899. #endif
  900. } // namespace detail
  901. template <unsigned digits10, mpfr_allocation_type AllocationType>
  902. struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
  903. {
  904. mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
  905. mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
  906. // rvalue copy
  907. mpfr_float_backend(mpfr_float_backend&& o) noexcept : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o))
  908. {}
  909. template <unsigned D, mpfr_allocation_type AT>
  910. mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
  911. : detail::mpfr_float_imp<digits10, AllocationType>()
  912. {
  913. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  914. }
  915. template <unsigned D, mpfr_allocation_type AT>
  916. explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
  917. : detail::mpfr_float_imp<digits10, AllocationType>()
  918. {
  919. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  920. }
  921. template <unsigned D>
  922. mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<D <= digits10>::type* = nullptr)
  923. : detail::mpfr_float_imp<digits10, AllocationType>()
  924. {
  925. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  926. }
  927. template <unsigned D>
  928. mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<!(D <= digits10)>::type* = nullptr)
  929. : detail::mpfr_float_imp<digits10, AllocationType>()
  930. {
  931. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  932. }
  933. mpfr_float_backend(const gmp_int& val)
  934. : detail::mpfr_float_imp<digits10, AllocationType>()
  935. {
  936. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  937. }
  938. mpfr_float_backend(const gmp_rational& val)
  939. : detail::mpfr_float_imp<digits10, AllocationType>()
  940. {
  941. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  942. }
  943. mpfr_float_backend(const mpfr_t val)
  944. : detail::mpfr_float_imp<digits10, AllocationType>()
  945. {
  946. mpfr_set(this->m_data, val, GMP_RNDN);
  947. }
  948. mpfr_float_backend(const mpf_t val)
  949. : detail::mpfr_float_imp<digits10, AllocationType>()
  950. {
  951. mpfr_set_f(this->m_data, val, GMP_RNDN);
  952. }
  953. mpfr_float_backend(const mpz_t val)
  954. : detail::mpfr_float_imp<digits10, AllocationType>()
  955. {
  956. mpfr_set_z(this->m_data, val, GMP_RNDN);
  957. }
  958. mpfr_float_backend(const mpq_t val)
  959. : detail::mpfr_float_imp<digits10, AllocationType>()
  960. {
  961. mpfr_set_q(this->m_data, val, GMP_RNDN);
  962. }
  963. // Construction with precision: we ignore the precision here.
  964. template <class V>
  965. mpfr_float_backend(const V& o, unsigned)
  966. {
  967. *this = o;
  968. }
  969. mpfr_float_backend& operator=(const mpfr_float_backend& o)
  970. {
  971. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
  972. return *this;
  973. }
  974. // rvalue assign
  975. mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept
  976. {
  977. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
  978. return *this;
  979. }
  980. template <class V>
  981. typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<digits10, AllocationType>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
  982. {
  983. *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
  984. return *this;
  985. }
  986. mpfr_float_backend& operator=(const mpfr_t val)
  987. {
  988. if (this->m_data[0]._mpfr_d == nullptr)
  989. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  990. mpfr_set(this->m_data, val, GMP_RNDN);
  991. return *this;
  992. }
  993. mpfr_float_backend& operator=(const mpf_t val)
  994. {
  995. if (this->m_data[0]._mpfr_d == nullptr)
  996. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  997. mpfr_set_f(this->m_data, val, GMP_RNDN);
  998. return *this;
  999. }
  1000. mpfr_float_backend& operator=(const mpz_t val)
  1001. {
  1002. if (this->m_data[0]._mpfr_d == nullptr)
  1003. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1004. mpfr_set_z(this->m_data, val, GMP_RNDN);
  1005. return *this;
  1006. }
  1007. mpfr_float_backend& operator=(const mpq_t val)
  1008. {
  1009. if (this->m_data[0]._mpfr_d == nullptr)
  1010. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1011. mpfr_set_q(this->m_data, val, GMP_RNDN);
  1012. return *this;
  1013. }
  1014. // We don't change our precision here, this is a fixed precision type:
  1015. template <unsigned D, mpfr_allocation_type AT>
  1016. mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
  1017. {
  1018. if (this->m_data[0]._mpfr_d == nullptr)
  1019. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1020. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  1021. return *this;
  1022. }
  1023. template <unsigned D>
  1024. mpfr_float_backend& operator=(const gmp_float<D>& val)
  1025. {
  1026. if (this->m_data[0]._mpfr_d == nullptr)
  1027. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1028. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  1029. return *this;
  1030. }
  1031. mpfr_float_backend& operator=(const gmp_int& val)
  1032. {
  1033. if (this->m_data[0]._mpfr_d == nullptr)
  1034. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1035. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  1036. return *this;
  1037. }
  1038. mpfr_float_backend& operator=(const gmp_rational& val)
  1039. {
  1040. if (this->m_data[0]._mpfr_d == nullptr)
  1041. mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
  1042. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  1043. return *this;
  1044. }
  1045. };
  1046. template <>
  1047. struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
  1048. {
  1049. mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
  1050. mpfr_float_backend(const mpfr_t val)
  1051. : 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())))
  1052. {
  1053. mpfr_set(this->m_data, val, GMP_RNDN);
  1054. }
  1055. mpfr_float_backend(const mpf_t val)
  1056. : 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())))
  1057. {
  1058. mpfr_set_f(this->m_data, val, GMP_RNDN);
  1059. }
  1060. mpfr_float_backend(const mpz_t val)
  1061. : detail::mpfr_float_imp<0, allocate_dynamic>()
  1062. {
  1063. mpfr_set_z(this->m_data, val, GMP_RNDN);
  1064. }
  1065. mpfr_float_backend(const mpq_t val)
  1066. : detail::mpfr_float_imp<0, allocate_dynamic>()
  1067. {
  1068. mpfr_set_q(this->m_data, val, GMP_RNDN);
  1069. }
  1070. mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
  1071. // rvalue copy
  1072. 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))
  1073. {}
  1074. template <class V>
  1075. mpfr_float_backend(const V& o, unsigned digits10)
  1076. : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
  1077. {
  1078. *this = o;
  1079. }
  1080. #ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
  1081. mpfr_float_backend(const std::string_view& o, unsigned digits10)
  1082. : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
  1083. {
  1084. std::string s(o);
  1085. *this = s.c_str();
  1086. }
  1087. #endif
  1088. template <unsigned D>
  1089. mpfr_float_backend(const gmp_float<D>& val, unsigned digits10)
  1090. : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
  1091. {
  1092. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  1093. }
  1094. template <unsigned D>
  1095. mpfr_float_backend(const mpfr_float_backend<D>& val, unsigned digits10)
  1096. : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))
  1097. {
  1098. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  1099. }
  1100. template <unsigned D>
  1101. mpfr_float_backend(const mpfr_float_backend<D>& val)
  1102. : 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())))
  1103. {
  1104. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  1105. }
  1106. template <unsigned D>
  1107. mpfr_float_backend(const gmp_float<D>& val)
  1108. : 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())))
  1109. {
  1110. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  1111. }
  1112. mpfr_float_backend(const gmp_int& val)
  1113. : 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())))
  1114. {
  1115. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  1116. }
  1117. mpfr_float_backend(const gmp_rational& val)
  1118. : 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())))
  1119. {
  1120. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  1121. }
  1122. mpfr_float_backend& operator=(const mpfr_float_backend& o) = default;
  1123. // rvalue assign
  1124. mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept = default;
  1125. template <class V>
  1126. typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<0, allocate_dynamic>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
  1127. {
  1128. constexpr unsigned d10 = std::is_floating_point<V>::value ?
  1129. std::numeric_limits<V>::digits10 :
  1130. std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 :
  1131. 1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits);
  1132. if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1133. {
  1134. BOOST_IF_CONSTEXPR(std::is_floating_point<V>::value)
  1135. {
  1136. if (std::numeric_limits<V>::digits > mpfr_get_prec(this->data()))
  1137. mpfr_set_prec(this->data(), std::numeric_limits<V>::digits);
  1138. }
  1139. else
  1140. {
  1141. if(precision() < d10)
  1142. this->precision(d10);
  1143. }
  1144. }
  1145. *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
  1146. return *this;
  1147. }
  1148. mpfr_float_backend& operator=(const mpfr_t val)
  1149. {
  1150. if (this->m_data[0]._mpfr_d == nullptr)
  1151. 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())));
  1152. else if(preserve_all_precision())
  1153. mpfr_set_prec(this->m_data, mpfr_get_prec(val));
  1154. mpfr_set(this->m_data, val, GMP_RNDN);
  1155. return *this;
  1156. }
  1157. mpfr_float_backend& operator=(const mpf_t val)
  1158. {
  1159. if (this->m_data[0]._mpfr_d == nullptr)
  1160. 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())));
  1161. else if(preserve_all_precision())
  1162. mpfr_set_prec(this->m_data, static_cast<mpfr_prec_t>(mpf_get_prec(val)));
  1163. mpfr_set_f(this->m_data, val, GMP_RNDN);
  1164. return *this;
  1165. }
  1166. mpfr_float_backend& operator=(const mpz_t val)
  1167. {
  1168. if (this->m_data[0]._mpfr_d == nullptr)
  1169. mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(get_default_precision())));
  1170. mpfr_set_z(this->m_data, val, GMP_RNDN);
  1171. return *this;
  1172. }
  1173. mpfr_float_backend& operator=(const mpq_t val)
  1174. {
  1175. if (this->m_data[0]._mpfr_d == nullptr)
  1176. mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(get_default_precision())));
  1177. mpfr_set_q(this->m_data, val, GMP_RNDN);
  1178. return *this;
  1179. }
  1180. template <unsigned D>
  1181. mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
  1182. {
  1183. if (this->m_data[0]._mpfr_d == nullptr)
  1184. 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()));
  1185. else if (preserve_related_precision())
  1186. mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
  1187. mpfr_set(this->m_data, val.data(), GMP_RNDN);
  1188. return *this;
  1189. }
  1190. template <unsigned D>
  1191. mpfr_float_backend& operator=(const gmp_float<D>& val)
  1192. {
  1193. if (this->m_data[0]._mpfr_d == nullptr)
  1194. 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()));
  1195. else if (preserve_all_precision())
  1196. mpfr_set_prec(this->m_data, static_cast<mpfr_prec_t>(mpf_get_prec(val.data())));
  1197. mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
  1198. return *this;
  1199. }
  1200. mpfr_float_backend& operator=(const gmp_int& val)
  1201. {
  1202. if (this->m_data[0]._mpfr_d == nullptr)
  1203. {
  1204. unsigned requested_precision = this->thread_default_precision();
  1205. if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1206. {
  1207. unsigned d2 = static_cast<unsigned>(used_gmp_int_bits(val));
  1208. unsigned d10 = static_cast<unsigned>(1ULL + multiprecision::detail::digits2_2_10(d2));
  1209. if (d10 > requested_precision)
  1210. requested_precision = d10;
  1211. }
  1212. mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(requested_precision)));
  1213. }
  1214. else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1215. {
  1216. unsigned requested_precision = this->thread_default_precision();
  1217. unsigned d2 = static_cast<unsigned>(used_gmp_int_bits(val));
  1218. unsigned d10 = static_cast<unsigned>(1ULL + multiprecision::detail::digits2_2_10(d2));
  1219. if (d10 > requested_precision)
  1220. this->precision(d10);
  1221. }
  1222. mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
  1223. return *this;
  1224. }
  1225. mpfr_float_backend& operator=(const gmp_rational& val)
  1226. {
  1227. if (this->m_data[0]._mpfr_d == nullptr)
  1228. {
  1229. unsigned requested_precision = this->get_default_precision();
  1230. if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1231. {
  1232. unsigned d10 = static_cast<unsigned>(1u + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)));
  1233. if (d10 > requested_precision)
  1234. requested_precision = d10;
  1235. }
  1236. mpfr_init2(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2(requested_precision)));
  1237. }
  1238. else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
  1239. {
  1240. unsigned requested_precision = this->get_default_precision();
  1241. unsigned d10 = static_cast<unsigned>(1u + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)));
  1242. if (d10 > requested_precision)
  1243. this->precision(d10);
  1244. }
  1245. mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
  1246. return *this;
  1247. }
  1248. static unsigned default_precision() noexcept
  1249. {
  1250. return get_global_default_precision();
  1251. }
  1252. static void default_precision(unsigned v) noexcept
  1253. {
  1254. get_global_default_precision() = v;
  1255. }
  1256. static unsigned thread_default_precision() noexcept
  1257. {
  1258. return get_default_precision();
  1259. }
  1260. static void thread_default_precision(unsigned v) noexcept
  1261. {
  1262. get_default_precision() = v;
  1263. }
  1264. unsigned precision() const noexcept
  1265. {
  1266. return static_cast<unsigned>(multiprecision::detail::digits2_2_10(static_cast<unsigned long>(mpfr_get_prec(this->m_data))));
  1267. }
  1268. void precision(unsigned digits10) noexcept
  1269. {
  1270. mpfr_prec_round(this->m_data, static_cast<mpfr_prec_t>(multiprecision::detail::digits10_2_2((digits10))), GMP_RNDN);
  1271. }
  1272. //
  1273. // Variable precision options:
  1274. //
  1275. static variable_precision_options default_variable_precision_options()noexcept
  1276. {
  1277. return get_global_default_options();
  1278. }
  1279. static variable_precision_options thread_default_variable_precision_options()noexcept
  1280. {
  1281. return get_default_options();
  1282. }
  1283. static void default_variable_precision_options(variable_precision_options opts)
  1284. {
  1285. get_global_default_options() = opts;
  1286. }
  1287. static void thread_default_variable_precision_options(variable_precision_options opts)
  1288. {
  1289. get_default_options() = opts;
  1290. }
  1291. static bool preserve_source_precision()
  1292. {
  1293. return get_default_options() >= variable_precision_options::preserve_source_precision;
  1294. }
  1295. static bool preserve_related_precision()
  1296. {
  1297. return get_default_options() >= variable_precision_options::preserve_related_precision;
  1298. }
  1299. static bool preserve_all_precision()
  1300. {
  1301. return get_default_options() >= variable_precision_options::preserve_all_precision;
  1302. }
  1303. };
  1304. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  1305. 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)
  1306. {
  1307. return a.compare(b) == 0;
  1308. }
  1309. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  1310. 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)
  1311. {
  1312. return a.compare(b) < 0;
  1313. }
  1314. template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
  1315. 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)
  1316. {
  1317. return a.compare(b) > 0;
  1318. }
  1319. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1320. inline bool eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b)noexcept
  1321. {
  1322. return mpfr_equal_p(a.data(), b.data());
  1323. }
  1324. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1325. inline bool eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
  1326. {
  1327. return mpfr_less_p(a.data(), b.data());
  1328. }
  1329. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1330. inline bool eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
  1331. {
  1332. return mpfr_greater_p(a.data(), b.data());
  1333. }
  1334. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1335. inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  1336. {
  1337. mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
  1338. }
  1339. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1340. inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  1341. {
  1342. mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
  1343. }
  1344. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1345. inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  1346. {
  1347. if ((void*)&o == (void*)&result)
  1348. mpfr_sqr(result.data(), o.data(), GMP_RNDN);
  1349. else
  1350. mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
  1351. }
  1352. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1353. inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
  1354. {
  1355. mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
  1356. }
  1357. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1358. inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  1359. {
  1360. mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
  1361. }
  1362. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1363. inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  1364. {
  1365. mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
  1366. }
  1367. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1368. inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  1369. {
  1370. mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
  1371. }
  1372. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1373. inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
  1374. {
  1375. mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
  1376. }
  1377. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1378. inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
  1379. {
  1380. if (i > 0)
  1381. mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
  1382. else
  1383. mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
  1384. }
  1385. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1386. inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
  1387. {
  1388. if (i > 0)
  1389. mpfr_sub_ui(result.data(), result.data(), static_cast<typename std::make_unsigned<long>::type>(i), GMP_RNDN);
  1390. else
  1391. mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
  1392. }
  1393. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1394. inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
  1395. {
  1396. mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
  1397. if (i < 0)
  1398. mpfr_neg(result.data(), result.data(), GMP_RNDN);
  1399. }
  1400. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1401. inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
  1402. {
  1403. mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
  1404. if (i < 0)
  1405. mpfr_neg(result.data(), result.data(), GMP_RNDN);
  1406. }
  1407. //
  1408. // Specialised 3 arg versions of the basic operators:
  1409. //
  1410. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
  1411. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
  1412. {
  1413. mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
  1414. }
  1415. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1416. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1417. {
  1418. mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
  1419. }
  1420. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1421. inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1422. {
  1423. if (y < 0)
  1424. mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
  1425. else
  1426. mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
  1427. }
  1428. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1429. inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1430. {
  1431. mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
  1432. }
  1433. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1434. inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1435. {
  1436. if (x < 0)
  1437. {
  1438. mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
  1439. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1440. }
  1441. else
  1442. mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
  1443. }
  1444. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
  1445. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
  1446. {
  1447. mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
  1448. }
  1449. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1450. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1451. {
  1452. mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
  1453. }
  1454. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1455. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1456. {
  1457. if (y < 0)
  1458. mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
  1459. else
  1460. mpfr_sub_ui(a.data(), x.data(), static_cast<typename std::make_unsigned<long>::type>(y), GMP_RNDN);
  1461. }
  1462. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1463. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1464. {
  1465. mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
  1466. }
  1467. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1468. inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1469. {
  1470. if (x < 0)
  1471. {
  1472. mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
  1473. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1474. }
  1475. else
  1476. mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
  1477. }
  1478. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
  1479. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
  1480. {
  1481. if ((void*)&x == (void*)&y)
  1482. mpfr_sqr(a.data(), x.data(), GMP_RNDN);
  1483. else
  1484. mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
  1485. }
  1486. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1487. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1488. {
  1489. mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
  1490. }
  1491. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1492. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1493. {
  1494. if (y < 0)
  1495. {
  1496. mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
  1497. a.negate();
  1498. }
  1499. else
  1500. mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
  1501. }
  1502. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1503. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1504. {
  1505. mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
  1506. }
  1507. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1508. inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1509. {
  1510. if (x < 0)
  1511. {
  1512. mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
  1513. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1514. }
  1515. else
  1516. mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
  1517. }
  1518. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
  1519. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
  1520. {
  1521. mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
  1522. }
  1523. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1524. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
  1525. {
  1526. mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
  1527. }
  1528. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1529. inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
  1530. {
  1531. if (y < 0)
  1532. {
  1533. mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
  1534. a.negate();
  1535. }
  1536. else
  1537. mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
  1538. }
  1539. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1540. inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
  1541. {
  1542. mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
  1543. }
  1544. template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
  1545. inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
  1546. {
  1547. if (x < 0)
  1548. {
  1549. mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
  1550. mpfr_neg(a.data(), a.data(), GMP_RNDN);
  1551. }
  1552. else
  1553. mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
  1554. }
  1555. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1556. inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1557. {
  1558. return 0 != mpfr_zero_p(val.data());
  1559. }
  1560. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1561. inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1562. {
  1563. return mpfr_sgn(val.data());
  1564. }
  1565. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1566. inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1567. {
  1568. if (mpfr_nan_p(val.data()))
  1569. {
  1570. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1571. }
  1572. *result = mpfr_get_ui(val.data(), GMP_RNDZ);
  1573. }
  1574. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1575. inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1576. {
  1577. if (mpfr_nan_p(val.data()))
  1578. {
  1579. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1580. }
  1581. *result = mpfr_get_si(val.data(), GMP_RNDZ);
  1582. }
  1583. #ifdef _MPFR_H_HAVE_INTMAX_T
  1584. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1585. inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1586. {
  1587. if (mpfr_nan_p(val.data()))
  1588. {
  1589. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1590. }
  1591. *result = mpfr_get_uj(val.data(), GMP_RNDZ);
  1592. }
  1593. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1594. inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
  1595. {
  1596. if (mpfr_nan_p(val.data()))
  1597. {
  1598. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1599. }
  1600. *result = mpfr_get_sj(val.data(), GMP_RNDZ);
  1601. }
  1602. #endif
  1603. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1604. inline void eval_convert_to(float* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1605. {
  1606. *result = mpfr_get_flt(val.data(), GMP_RNDN);
  1607. }
  1608. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1609. inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1610. {
  1611. *result = mpfr_get_d(val.data(), GMP_RNDN);
  1612. }
  1613. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1614. inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1615. {
  1616. *result = mpfr_get_ld(val.data(), GMP_RNDN);
  1617. }
  1618. #ifdef BOOST_HAS_INT128
  1619. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1620. inline void eval_convert_to(int128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1621. {
  1622. gmp_int i;
  1623. mpfr_get_z(i.data(), val.data(), GMP_RNDN);
  1624. eval_convert_to(result, i);
  1625. }
  1626. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1627. inline void eval_convert_to(uint128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1628. {
  1629. gmp_int i;
  1630. mpfr_get_z(i.data(), val.data(), GMP_RNDN);
  1631. eval_convert_to(result, i);
  1632. }
  1633. #endif
  1634. #if defined(BOOST_HAS_FLOAT128)
  1635. template <unsigned digits10, mpfr_allocation_type AllocationType>
  1636. inline void eval_convert_to(float128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
  1637. {
  1638. *result = float128_procs::strtoflt128(val.str(0, std::ios_base::scientific).c_str(), nullptr);
  1639. }
  1640. #endif
  1641. //
  1642. // Native non-member operations:
  1643. //
  1644. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1645. inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1646. {
  1647. mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
  1648. }
  1649. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1650. inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1651. {
  1652. mpfr_abs(result.data(), val.data(), GMP_RNDN);
  1653. }
  1654. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1655. inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1656. {
  1657. mpfr_abs(result.data(), val.data(), GMP_RNDN);
  1658. }
  1659. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1660. inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1661. {
  1662. mpfr_ceil(result.data(), val.data());
  1663. }
  1664. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1665. inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1666. {
  1667. mpfr_floor(result.data(), val.data());
  1668. }
  1669. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1670. inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
  1671. {
  1672. mpfr_trunc(result.data(), val.data());
  1673. }
  1674. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1675. inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
  1676. {
  1677. using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
  1678. if (e > 0)
  1679. mpfr_mul_2exp(result.data(), val.data(), static_cast<local_uint_type>(e), GMP_RNDN);
  1680. else if (e < 0)
  1681. mpfr_div_2exp(result.data(), val.data(), static_cast<local_uint_type>(-e), GMP_RNDN);
  1682. else
  1683. result = val;
  1684. }
  1685. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1686. inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
  1687. {
  1688. if (mpfr_zero_p(val.data()))
  1689. {
  1690. *e = 0;
  1691. result = val;
  1692. return;
  1693. }
  1694. mp_exp_t v = mpfr_get_exp(val.data());
  1695. *e = static_cast<int>(v);
  1696. if (v)
  1697. eval_ldexp(result, val, -v);
  1698. else
  1699. result = val;
  1700. }
  1701. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1702. inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
  1703. {
  1704. if (mpfr_zero_p(val.data()))
  1705. {
  1706. *e = 0;
  1707. result = val;
  1708. return;
  1709. }
  1710. mp_exp_t v = mpfr_get_exp(val.data());
  1711. *e = v;
  1712. if(v)
  1713. eval_ldexp(result, val, -v);
  1714. else
  1715. result = val;
  1716. }
  1717. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1718. inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) noexcept
  1719. {
  1720. return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
  1721. }
  1722. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1723. inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
  1724. {
  1725. 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))
  1726. {
  1727. mpfr_set(result.data(), b.data(), GMP_RNDN);
  1728. }
  1729. else
  1730. mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
  1731. }
  1732. #ifdef BOOST_MSVC
  1733. //
  1734. // The enable_if usage below doesn't work with msvc - but only when
  1735. // certain other enable_if usages are defined first. It's a capricious
  1736. // and rather annoying compiler bug in other words....
  1737. //
  1738. #define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10)&&
  1739. #else
  1740. #define BOOST_MP_ENABLE_IF_WORKAROUND
  1741. #endif
  1742. template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
  1743. 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
  1744. eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
  1745. {
  1746. mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
  1747. }
  1748. template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
  1749. inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value && (BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long)))>::type
  1750. eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
  1751. {
  1752. mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
  1753. }
  1754. #undef BOOST_MP_ENABLE_IF_WORKAROUND
  1755. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1756. inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1757. {
  1758. mpfr_exp(result.data(), arg.data(), GMP_RNDN);
  1759. }
  1760. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1761. inline void eval_exp2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1762. {
  1763. mpfr_exp2(result.data(), arg.data(), GMP_RNDN);
  1764. }
  1765. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1766. inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1767. {
  1768. mpfr_log(result.data(), arg.data(), GMP_RNDN);
  1769. }
  1770. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1771. inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1772. {
  1773. mpfr_log10(result.data(), arg.data(), GMP_RNDN);
  1774. }
  1775. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1776. inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1777. {
  1778. mpfr_sin(result.data(), arg.data(), GMP_RNDN);
  1779. }
  1780. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1781. inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1782. {
  1783. mpfr_cos(result.data(), arg.data(), GMP_RNDN);
  1784. }
  1785. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1786. inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1787. {
  1788. mpfr_tan(result.data(), arg.data(), GMP_RNDN);
  1789. }
  1790. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1791. inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1792. {
  1793. mpfr_asin(result.data(), arg.data(), GMP_RNDN);
  1794. }
  1795. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1796. inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1797. {
  1798. mpfr_acos(result.data(), arg.data(), GMP_RNDN);
  1799. }
  1800. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1801. inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1802. {
  1803. mpfr_atan(result.data(), arg.data(), GMP_RNDN);
  1804. }
  1805. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1806. inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
  1807. {
  1808. mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
  1809. }
  1810. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1811. inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1812. {
  1813. mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
  1814. }
  1815. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1816. inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1817. {
  1818. mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
  1819. }
  1820. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1821. inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1822. {
  1823. mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
  1824. }
  1825. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1826. inline void eval_log2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
  1827. {
  1828. mpfr_log2(result.data(), arg.data(), GMP_RNDN);
  1829. }
  1830. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1831. inline void eval_modf(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg, mpfr_float_backend<Digits10, AllocateType>* pipart)
  1832. {
  1833. if (pipart == nullptr)
  1834. {
  1835. mpfr_float_backend<Digits10, AllocateType> ipart;
  1836. mpfr_modf(ipart.data(), result.data(), arg.data(), GMP_RNDN);
  1837. }
  1838. else
  1839. {
  1840. mpfr_modf(pipart->data(), result.data(), arg.data(), GMP_RNDN);
  1841. }
  1842. }
  1843. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1844. inline void eval_remainder(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
  1845. {
  1846. mpfr_remainder(result.data(), a.data(), b.data(), GMP_RNDN);
  1847. }
  1848. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1849. 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)
  1850. {
  1851. long l;
  1852. mpfr_remquo(result.data(), &l, a.data(), b.data(), GMP_RNDN);
  1853. if (pi)
  1854. *pi = static_cast<int>(l);
  1855. }
  1856. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1857. inline void eval_fmod(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
  1858. {
  1859. mpfr_fmod(result.data(), a.data(), b.data(), GMP_RNDN);
  1860. }
  1861. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1862. 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)
  1863. {
  1864. mpfr_fma(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
  1865. }
  1866. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1867. 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)
  1868. {
  1869. mpfr_fma(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
  1870. }
  1871. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1872. 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)
  1873. {
  1874. mpfr_fms(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
  1875. result.negate();
  1876. }
  1877. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1878. 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)
  1879. {
  1880. mpfr_fms(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
  1881. }
  1882. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1883. inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const mpfr_float_backend<Digits10, AllocateType>& arg)
  1884. {
  1885. return (arg.data()[0]._mpfr_sign < 0) ? 1 : 0;
  1886. }
  1887. template <unsigned Digits10, mpfr_allocation_type AllocateType>
  1888. inline std::size_t hash_value(const mpfr_float_backend<Digits10, AllocateType>& val)
  1889. {
  1890. std::size_t result = 0;
  1891. std::size_t len = val.data()[0]._mpfr_prec / mp_bits_per_limb;
  1892. if (val.data()[0]._mpfr_prec % mp_bits_per_limb)
  1893. ++len;
  1894. for (std::size_t i = 0; i < len; ++i)
  1895. boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_d[i]);
  1896. boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_exp, val.data()[0]._mpfr_sign);
  1897. return result;
  1898. }
  1899. } // namespace backends
  1900. namespace detail {
  1901. template <>
  1902. struct is_variable_precision<backends::mpfr_float_backend<0> > : public std::integral_constant<bool, true>
  1903. {};
  1904. } // namespace detail
  1905. template <>
  1906. struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public std::integral_constant<int, number_kind_floating_point>
  1907. {};
  1908. template <unsigned D, boost::multiprecision::mpfr_allocation_type A1, boost::multiprecision::mpfr_allocation_type A2>
  1909. struct is_equivalent_number_type<backends::mpfr_float_backend<D, A1>, backends::mpfr_float_backend<D, A2> > : public std::integral_constant<bool, true> {};
  1910. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1911. 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)
  1912. {
  1913. return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(-a) : a;
  1914. }
  1915. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  1916. 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)
  1917. {
  1918. 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;
  1919. }
  1920. } // namespace multiprecision
  1921. namespace math {
  1922. using boost::multiprecision::copysign;
  1923. using boost::multiprecision::signbit;
  1924. namespace tools {
  1925. #ifndef BOOST_MP_MATH_AVAILABLE
  1926. template <typename T>
  1927. inline int digits();
  1928. template <typename T>
  1929. inline T max_value();
  1930. template <typename T>
  1931. inline T min_value();
  1932. #endif
  1933. inline void set_output_precision(const boost::multiprecision::mpfr_float& val, std::ostream& os)
  1934. {
  1935. os << std::setprecision(static_cast<int>(val.precision()));
  1936. }
  1937. template <>
  1938. inline int digits<boost::multiprecision::mpfr_float>()
  1939. #ifdef BOOST_MATH_NOEXCEPT
  1940. noexcept
  1941. #endif
  1942. {
  1943. return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision()));
  1944. }
  1945. template <>
  1946. inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
  1947. #ifdef BOOST_MATH_NOEXCEPT
  1948. noexcept
  1949. #endif
  1950. {
  1951. return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision()));
  1952. }
  1953. template <>
  1954. inline boost::multiprecision::mpfr_float
  1955. max_value<boost::multiprecision::mpfr_float>()
  1956. {
  1957. boost::multiprecision::mpfr_float result(0.5);
  1958. mpfr_mul_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(mpfr_get_emax()), GMP_RNDN);
  1959. BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
  1960. return result;
  1961. }
  1962. template <>
  1963. inline boost::multiprecision::mpfr_float
  1964. min_value<boost::multiprecision::mpfr_float>()
  1965. {
  1966. boost::multiprecision::mpfr_float result(0.5);
  1967. mpfr_div_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(-mpfr_get_emin()), GMP_RNDN);
  1968. BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
  1969. return result;
  1970. }
  1971. template <>
  1972. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
  1973. max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
  1974. {
  1975. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
  1976. mpfr_mul_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(mpfr_get_emax()), GMP_RNDN);
  1977. BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
  1978. return result;
  1979. }
  1980. template <>
  1981. inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
  1982. min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
  1983. {
  1984. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
  1985. mpfr_div_2exp(result.backend().data(), result.backend().data(), static_cast<typename std::make_unsigned<mpfr_exp_t>::type>(-mpfr_get_emin()), GMP_RNDN);
  1986. BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
  1987. return result;
  1988. }
  1989. //
  1990. // Over again with debug_adaptor:
  1991. //
  1992. template <>
  1993. inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  1994. #ifdef BOOST_MATH_NOEXCEPT
  1995. noexcept
  1996. #endif
  1997. {
  1998. 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()));
  1999. }
  2000. template <>
  2001. inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2002. #ifdef BOOST_MATH_NOEXCEPT
  2003. noexcept
  2004. #endif
  2005. {
  2006. 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()));
  2007. }
  2008. template <>
  2009. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
  2010. max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2011. {
  2012. return max_value<boost::multiprecision::mpfr_float>().backend();
  2013. }
  2014. template <>
  2015. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
  2016. min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2017. {
  2018. return min_value<boost::multiprecision::mpfr_float>().backend();
  2019. }
  2020. template <>
  2021. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
  2022. max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2023. {
  2024. return max_value<boost::multiprecision::mpfr_float>().backend();
  2025. }
  2026. template <>
  2027. inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
  2028. min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2029. {
  2030. return min_value<boost::multiprecision::mpfr_float>().backend();
  2031. }
  2032. //
  2033. // Over again with logged_adaptor:
  2034. //
  2035. template <>
  2036. inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2037. #ifdef BOOST_MATH_NOEXCEPT
  2038. noexcept
  2039. #endif
  2040. {
  2041. 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()));
  2042. }
  2043. template <>
  2044. inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2045. #ifdef BOOST_MATH_NOEXCEPT
  2046. noexcept
  2047. #endif
  2048. {
  2049. 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()));
  2050. }
  2051. template <>
  2052. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
  2053. max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2054. {
  2055. return max_value<boost::multiprecision::mpfr_float>().backend();
  2056. }
  2057. template <>
  2058. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
  2059. min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
  2060. {
  2061. return min_value<boost::multiprecision::mpfr_float>().backend();
  2062. }
  2063. template <>
  2064. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
  2065. max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2066. {
  2067. return max_value<boost::multiprecision::mpfr_float>().backend();
  2068. }
  2069. template <>
  2070. inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
  2071. min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
  2072. {
  2073. return min_value<boost::multiprecision::mpfr_float>().backend();
  2074. }
  2075. } // namespace tools
  2076. namespace constants { namespace detail {
  2077. template <class T>
  2078. struct constant_pi;
  2079. template <class T>
  2080. struct constant_ln_two;
  2081. template <class T>
  2082. struct constant_euler;
  2083. template <class T>
  2084. struct constant_catalan;
  2085. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2086. struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  2087. {
  2088. using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  2089. template <int N>
  2090. static inline const result_type& get(const std::integral_constant<int, N>&)
  2091. {
  2092. // Rely on C++11 thread safe initialization:
  2093. static result_type result{get(std::integral_constant<int, 0>())};
  2094. return result;
  2095. }
  2096. static inline const result_type get(const std::integral_constant<int, 0>&)
  2097. {
  2098. result_type result;
  2099. mpfr_const_pi(result.backend().data(), GMP_RNDN);
  2100. return result;
  2101. }
  2102. };
  2103. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2104. struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  2105. {
  2106. using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  2107. template <int N>
  2108. static inline const result_type& get(const std::integral_constant<int, N>&)
  2109. {
  2110. // Rely on C++11 thread safe initialization:
  2111. static result_type result{get(std::integral_constant<int, 0>())};
  2112. return result;
  2113. }
  2114. static inline const result_type get(const std::integral_constant<int, 0>&)
  2115. {
  2116. result_type result;
  2117. mpfr_const_log2(result.backend().data(), GMP_RNDN);
  2118. return result;
  2119. }
  2120. };
  2121. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2122. struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  2123. {
  2124. using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  2125. template <int N>
  2126. static inline const result_type& get(const std::integral_constant<int, N>&)
  2127. {
  2128. // Rely on C++11 thread safe initialization:
  2129. static result_type result{get(std::integral_constant<int, 0>())};
  2130. return result;
  2131. }
  2132. static inline const result_type get(const std::integral_constant<int, 0>&)
  2133. {
  2134. result_type result;
  2135. mpfr_const_euler(result.backend().data(), GMP_RNDN);
  2136. return result;
  2137. }
  2138. };
  2139. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2140. struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  2141. {
  2142. using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  2143. template <int N>
  2144. static inline const result_type& get(const std::integral_constant<int, N>&)
  2145. {
  2146. // Rely on C++11 thread safe initialization:
  2147. static result_type result{get(std::integral_constant<int, 0>())};
  2148. return result;
  2149. }
  2150. static inline const result_type get(const std::integral_constant<int, 0>&)
  2151. {
  2152. result_type result;
  2153. mpfr_const_catalan(result.backend().data(), GMP_RNDN);
  2154. return result;
  2155. }
  2156. };
  2157. //
  2158. // Over again with debug_adaptor:
  2159. //
  2160. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2161. struct constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2162. {
  2163. using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2164. template <int N>
  2165. static inline const result_type& get(const std::integral_constant<int, N>&)
  2166. {
  2167. // Rely on C++11 thread safe initialization:
  2168. static result_type result{get(std::integral_constant<int, 0>())};
  2169. return result;
  2170. }
  2171. static inline const result_type get(const std::integral_constant<int, 0>&)
  2172. {
  2173. result_type result;
  2174. mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
  2175. result.backend().update_view();
  2176. return result;
  2177. }
  2178. };
  2179. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2180. struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2181. {
  2182. using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2183. template <int N>
  2184. static inline const result_type& get(const std::integral_constant<int, N>&)
  2185. {
  2186. // Rely on C++11 thread safe initialization:
  2187. static result_type result{get(std::integral_constant<int, 0>())};
  2188. return result;
  2189. }
  2190. static inline const result_type get(const std::integral_constant<int, 0>&)
  2191. {
  2192. result_type result;
  2193. mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
  2194. result.backend().update_view();
  2195. return result;
  2196. }
  2197. };
  2198. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2199. struct constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2200. {
  2201. using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2202. template <int N>
  2203. static inline const result_type& get(const std::integral_constant<int, N>&)
  2204. {
  2205. // Rely on C++11 thread safe initialization:
  2206. static result_type result{get(std::integral_constant<int, 0>())};
  2207. return result;
  2208. }
  2209. static inline const result_type get(const std::integral_constant<int, 0>&)
  2210. {
  2211. result_type result;
  2212. mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
  2213. result.backend().update_view();
  2214. return result;
  2215. }
  2216. };
  2217. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2218. struct constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2219. {
  2220. using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2221. template <int N>
  2222. static inline const result_type& get(const std::integral_constant<int, N>&)
  2223. {
  2224. // Rely on C++11 thread safe initialization:
  2225. static result_type result{get(std::integral_constant<int, 0>())};
  2226. return result;
  2227. }
  2228. static inline const result_type get(const std::integral_constant<int, 0>&)
  2229. {
  2230. result_type result;
  2231. mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
  2232. result.backend().update_view();
  2233. return result;
  2234. }
  2235. };
  2236. //
  2237. // Over again with logged_adaptor:
  2238. //
  2239. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2240. struct constant_pi<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2241. {
  2242. using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2243. template <int N>
  2244. static inline const result_type& get(const std::integral_constant<int, N>&)
  2245. {
  2246. // C++11 thread safe static initialization:
  2247. static result_type result{get(std::integral_constant<int, 0>())};
  2248. return result;
  2249. }
  2250. static inline const result_type get(const std::integral_constant<int, 0>&)
  2251. {
  2252. result_type result;
  2253. mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
  2254. return result;
  2255. }
  2256. };
  2257. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2258. struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2259. {
  2260. using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2261. template <int N>
  2262. static inline const result_type& get(const std::integral_constant<int, N>&)
  2263. {
  2264. // C++11 thread safe static initialization:
  2265. static result_type result{get(std::integral_constant<int, 0>())};
  2266. return result;
  2267. }
  2268. static inline const result_type get(const std::integral_constant<int, 0>&)
  2269. {
  2270. result_type result;
  2271. mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
  2272. return result;
  2273. }
  2274. };
  2275. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2276. struct constant_euler<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2277. {
  2278. using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2279. template <int N>
  2280. static inline const result_type& get(const std::integral_constant<int, N>&)
  2281. {
  2282. // C++11 thread safe static initialization:
  2283. static result_type result{get(std::integral_constant<int, 0>())};
  2284. return result;
  2285. }
  2286. static inline const result_type get(const std::integral_constant<int, 0>&)
  2287. {
  2288. result_type result;
  2289. mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
  2290. return result;
  2291. }
  2292. };
  2293. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2294. struct constant_catalan<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
  2295. {
  2296. using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
  2297. template <int N>
  2298. static inline const result_type& get(const std::integral_constant<int, N>&)
  2299. {
  2300. // C++11 thread safe static initialization:
  2301. static result_type result{get(std::integral_constant<int, 0>())};
  2302. return result;
  2303. }
  2304. static inline const result_type get(const std::integral_constant<int, 0>&)
  2305. {
  2306. result_type result;
  2307. mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
  2308. return result;
  2309. }
  2310. };
  2311. }} // namespace constants::detail
  2312. } // namespace math
  2313. namespace multiprecision {
  2314. //
  2315. // Overloaded special functions which call native mpfr routines:
  2316. //
  2317. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2318. 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)
  2319. {
  2320. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2321. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2322. mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2323. return result;
  2324. }
  2325. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2326. 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)
  2327. {
  2328. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2329. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2330. mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2331. return result;
  2332. }
  2333. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2334. 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)
  2335. {
  2336. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2337. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2338. mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2339. return result;
  2340. }
  2341. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2342. 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)
  2343. {
  2344. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2345. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2346. mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2347. return result;
  2348. }
  2349. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2350. 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)
  2351. {
  2352. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2353. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2354. mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2355. return result;
  2356. }
  2357. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2358. 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)
  2359. {
  2360. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2361. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2362. mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2363. return result;
  2364. }
  2365. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2366. 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)
  2367. {
  2368. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2369. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2370. mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2371. return result;
  2372. }
  2373. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2374. 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)
  2375. {
  2376. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2377. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2378. mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2379. return result;
  2380. }
  2381. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2382. 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)
  2383. {
  2384. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2385. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2386. mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2387. return result;
  2388. }
  2389. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2390. 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)
  2391. {
  2392. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2393. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2394. mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2395. return result;
  2396. }
  2397. //
  2398. // Over again with debug_adaptor:
  2399. //
  2400. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2401. 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)
  2402. {
  2403. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2404. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2405. mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2406. result.backend().update_view();
  2407. return result;
  2408. }
  2409. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2410. 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)
  2411. {
  2412. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2413. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2414. mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2415. result.backend().update_view();
  2416. return result;
  2417. }
  2418. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2419. 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)
  2420. {
  2421. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2422. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2423. mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2424. result.backend().update_view();
  2425. return result;
  2426. }
  2427. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2428. 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)
  2429. {
  2430. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2431. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2432. mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2433. result.backend().update_view();
  2434. return result;
  2435. }
  2436. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2437. 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)
  2438. {
  2439. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2440. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2441. mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2442. result.backend().update_view();
  2443. return result;
  2444. }
  2445. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2446. 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)
  2447. {
  2448. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2449. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2450. mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2451. result.backend().update_view();
  2452. return result;
  2453. }
  2454. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2455. 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)
  2456. {
  2457. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2458. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2459. mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2460. result.backend().update_view();
  2461. return result;
  2462. }
  2463. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2464. 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)
  2465. {
  2466. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2467. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2468. mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2469. result.backend().update_view();
  2470. return result;
  2471. }
  2472. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2473. 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)
  2474. {
  2475. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2476. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2477. mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2478. result.backend().update_view();
  2479. return result;
  2480. }
  2481. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2482. 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)
  2483. {
  2484. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2485. boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2486. mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2487. result.backend().update_view();
  2488. return result;
  2489. }
  2490. //
  2491. // Over again with logged_adaptor:
  2492. //
  2493. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2494. 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)
  2495. {
  2496. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2497. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2498. mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2499. return result;
  2500. }
  2501. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2502. 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)
  2503. {
  2504. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2505. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2506. mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2507. return result;
  2508. }
  2509. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2510. 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)
  2511. {
  2512. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2513. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2514. mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2515. return result;
  2516. }
  2517. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2518. 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)
  2519. {
  2520. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2521. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2522. mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2523. return result;
  2524. }
  2525. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2526. 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)
  2527. {
  2528. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2529. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2530. mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2531. return result;
  2532. }
  2533. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2534. 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)
  2535. {
  2536. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2537. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2538. mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2539. return result;
  2540. }
  2541. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2542. 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)
  2543. {
  2544. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2545. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2546. mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2547. return result;
  2548. }
  2549. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2550. 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)
  2551. {
  2552. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2553. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2554. mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2555. return result;
  2556. }
  2557. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2558. 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)
  2559. {
  2560. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2561. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2562. mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2563. return result;
  2564. }
  2565. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2566. 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)
  2567. {
  2568. boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
  2569. boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
  2570. mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
  2571. return result;
  2572. }
  2573. } // namespace multiprecision
  2574. namespace math {
  2575. //
  2576. // Overloaded special functions which call native mpfr routines:
  2577. //
  2578. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2579. 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&)
  2580. {
  2581. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2582. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2583. mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2584. if (mpfr_inf_p(result.backend().data()))
  2585. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("asinh<%1%>(%1%)", nullptr, Policy());
  2586. if (mpfr_nan_p(result.backend().data()))
  2587. return policies::raise_evaluation_error("asinh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
  2588. return result;
  2589. }
  2590. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2591. 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)
  2592. {
  2593. return asinh(arg, policies::policy<>());
  2594. }
  2595. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2596. 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&)
  2597. {
  2598. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2599. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2600. mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2601. if (mpfr_inf_p(result.backend().data()))
  2602. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("acosh<%1%>(%1%)", nullptr, Policy());
  2603. if (mpfr_nan_p(result.backend().data()))
  2604. return policies::raise_evaluation_error("acosh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
  2605. return result;
  2606. }
  2607. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2608. 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)
  2609. {
  2610. return acosh(arg, policies::policy<>());
  2611. }
  2612. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2613. 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& )
  2614. {
  2615. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2616. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2617. mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2618. if (mpfr_inf_p(result.backend().data()))
  2619. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("atanh<%1%>(%1%)", nullptr, Policy());
  2620. if (mpfr_nan_p(result.backend().data()))
  2621. return policies::raise_evaluation_error("atanh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
  2622. return result;
  2623. }
  2624. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2625. 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)
  2626. {
  2627. return atanh(arg, policies::policy<>());
  2628. }
  2629. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2630. 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&)
  2631. {
  2632. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2633. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2634. if (mpfr_nan_p(arg.backend().data()))
  2635. return policies::raise_domain_error("cbrt<%1%>(%1%)", "Input is a NaN", result, Policy());
  2636. mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2637. if (mpfr_inf_p(result.backend().data()))
  2638. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("cbrt<%1%>(%1%)", nullptr, Policy());
  2639. if (mpfr_nan_p(result.backend().data()))
  2640. return policies::raise_evaluation_error("cbrt<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
  2641. return result;
  2642. }
  2643. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2644. 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)
  2645. {
  2646. return cbrt(arg, policies::policy<>());
  2647. }
  2648. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2649. 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)
  2650. {
  2651. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2652. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2653. if (mpfr_nan_p(arg.backend().data()))
  2654. return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
  2655. mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2656. if (mpfr_inf_p(result.backend().data()))
  2657. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erf<%1%>(%1%)", nullptr, pol);
  2658. if (mpfr_nan_p(result.backend().data()))
  2659. return policies::raise_evaluation_error("erf<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2660. return result;
  2661. }
  2662. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2663. 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)
  2664. {
  2665. return erf(arg, policies::policy<>());
  2666. }
  2667. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2668. 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)
  2669. {
  2670. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2671. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2672. if (mpfr_nan_p(arg.backend().data()))
  2673. return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
  2674. mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2675. if (mpfr_inf_p(result.backend().data()))
  2676. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erfc<%1%>(%1%)", nullptr, pol);
  2677. if (mpfr_nan_p(result.backend().data()))
  2678. return policies::raise_evaluation_error("erfc<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2679. return result;
  2680. }
  2681. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2682. 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)
  2683. {
  2684. return erfc(arg, policies::policy<>());
  2685. }
  2686. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2687. 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)
  2688. {
  2689. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2690. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2691. if (mpfr_nan_p(arg.backend().data()))
  2692. return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
  2693. mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2694. if (mpfr_inf_p(result.backend().data()))
  2695. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("expm1<%1%>(%1%)", nullptr, pol);
  2696. if (mpfr_nan_p(result.backend().data()))
  2697. return policies::raise_evaluation_error("expm1<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2698. return result;
  2699. }
  2700. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2701. 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)
  2702. {
  2703. return expm1(arg, policies::policy<>());
  2704. }
  2705. #ifdef BOOST_MP_MATH_AVAILABLE
  2706. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2707. 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)
  2708. {
  2709. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2710. (void)precision_guard; // warning suppression
  2711. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2712. if (arg > 0)
  2713. {
  2714. mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2715. if (sign)
  2716. *sign = 1;
  2717. }
  2718. else
  2719. {
  2720. if (floor(arg) == arg)
  2721. return policies::raise_pole_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >(
  2722. "lgamma<%1%>", "Evaluation of lgamma at a negative integer %1%.", arg, pol);
  2723. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> t = detail::sinpx(arg);
  2724. arg = -arg;
  2725. if (t < 0)
  2726. {
  2727. t = -t;
  2728. }
  2729. 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);
  2730. if (sign)
  2731. {
  2732. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> phase = 1 - arg;
  2733. phase = floor(phase) / 2;
  2734. if (floor(phase) == phase)
  2735. *sign = -1;
  2736. else
  2737. *sign = 1;
  2738. }
  2739. }
  2740. if (mpfr_inf_p(result.backend().data()))
  2741. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("lgamma<%1%>(%1%)", nullptr, pol);
  2742. if (mpfr_nan_p(result.backend().data()))
  2743. return policies::raise_evaluation_error("lgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2744. return result;
  2745. }
  2746. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2747. 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)
  2748. {
  2749. return lgamma(arg, sign, policies::policy<>());
  2750. }
  2751. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2752. 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)
  2753. {
  2754. return lgamma(arg, 0, pol);
  2755. }
  2756. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2757. 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)
  2758. {
  2759. return lgamma(arg, 0, policies::policy<>());
  2760. }
  2761. #endif // BOOST_MP_MATH_AVAILABLE
  2762. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2763. 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)
  2764. {
  2765. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2766. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2767. mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2768. if (mpfr_inf_p(result.backend().data()))
  2769. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("tgamma<%1%>(%1%)", nullptr, pol);
  2770. if (mpfr_nan_p(result.backend().data()))
  2771. return policies::raise_evaluation_error("tgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2772. return result;
  2773. }
  2774. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2775. 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)
  2776. {
  2777. return tgamma(arg, policies::policy<>());
  2778. }
  2779. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2780. 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)
  2781. {
  2782. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2783. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2784. mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2785. if (mpfr_inf_p(result.backend().data()))
  2786. 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);
  2787. if (mpfr_nan_p(result.backend().data()))
  2788. return policies::raise_evaluation_error("log1p<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
  2789. return result;
  2790. }
  2791. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2792. 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)
  2793. {
  2794. return log1p(arg, policies::policy<>());
  2795. }
  2796. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2797. 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)
  2798. {
  2799. boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
  2800. boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
  2801. mpfr_rec_sqrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
  2802. if (mpfr_inf_p(result.backend().data()))
  2803. return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("rsqrt<%1%>(%1%)", nullptr, pol);
  2804. if (mpfr_nan_p(result.backend().data()))
  2805. return policies::raise_evaluation_error("rsqrt<%1%>(%1%)", "Negative argument, result is a NaN", result, pol);
  2806. return result;
  2807. }
  2808. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2809. 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)
  2810. {
  2811. return rsqrt(arg, policies::policy<>());
  2812. }
  2813. //
  2814. // Over again with debug_adaptor:
  2815. //
  2816. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2817. 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)
  2818. {
  2819. return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2820. }
  2821. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2822. 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)
  2823. {
  2824. return asinh(arg, policies::policy<>());
  2825. }
  2826. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2827. 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)
  2828. {
  2829. return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2830. }
  2831. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2832. 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)
  2833. {
  2834. return acosh(arg, policies::policy<>());
  2835. }
  2836. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2837. 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)
  2838. {
  2839. return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2840. }
  2841. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2842. 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)
  2843. {
  2844. return atanh(arg, policies::policy<>());
  2845. }
  2846. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2847. 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)
  2848. {
  2849. return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2850. }
  2851. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2852. 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)
  2853. {
  2854. return cbrt(arg, policies::policy<>());
  2855. }
  2856. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2857. 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)
  2858. {
  2859. return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2860. }
  2861. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2862. 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)
  2863. {
  2864. return erf(arg, policies::policy<>());
  2865. }
  2866. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2867. 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)
  2868. {
  2869. return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2870. }
  2871. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2872. 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)
  2873. {
  2874. return erfc(arg, policies::policy<>());
  2875. }
  2876. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2877. 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)
  2878. {
  2879. return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2880. }
  2881. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2882. 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)
  2883. {
  2884. return expm1(arg, policies::policy<>());
  2885. }
  2886. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2887. 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)
  2888. {
  2889. return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
  2890. }
  2891. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2892. 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)
  2893. {
  2894. return lgamma(arg, sign, policies::policy<>());
  2895. }
  2896. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2897. 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)
  2898. {
  2899. return lgamma(arg, 0, pol);
  2900. }
  2901. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2902. 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)
  2903. {
  2904. return lgamma(arg, 0, policies::policy<>());
  2905. }
  2906. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2907. 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)
  2908. {
  2909. return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2910. }
  2911. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2912. 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)
  2913. {
  2914. return tgamma(arg, policies::policy<>());
  2915. }
  2916. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2917. 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)
  2918. {
  2919. return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2920. }
  2921. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2922. 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)
  2923. {
  2924. return log1p(arg, policies::policy<>());
  2925. }
  2926. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2927. 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)
  2928. {
  2929. return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2930. }
  2931. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2932. 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)
  2933. {
  2934. return rsqrt(arg, policies::policy<>());
  2935. }
  2936. //
  2937. // Over again with logged_adaptor:
  2938. //
  2939. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2940. 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)
  2941. {
  2942. return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2943. }
  2944. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2945. 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)
  2946. {
  2947. return asinh(arg, policies::policy<>());
  2948. }
  2949. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2950. 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)
  2951. {
  2952. return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2953. }
  2954. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2955. 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)
  2956. {
  2957. return acosh(arg, policies::policy<>());
  2958. }
  2959. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2960. 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)
  2961. {
  2962. return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2963. }
  2964. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2965. 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)
  2966. {
  2967. return atanh(arg, policies::policy<>());
  2968. }
  2969. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2970. 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)
  2971. {
  2972. return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2973. }
  2974. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2975. 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)
  2976. {
  2977. return cbrt(arg, policies::policy<>());
  2978. }
  2979. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2980. 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)
  2981. {
  2982. return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2983. }
  2984. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2985. 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)
  2986. {
  2987. return erf(arg, policies::policy<>());
  2988. }
  2989. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  2990. 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)
  2991. {
  2992. return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  2993. }
  2994. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  2995. 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)
  2996. {
  2997. return erfc(arg, policies::policy<>());
  2998. }
  2999. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3000. 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)
  3001. {
  3002. return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  3003. }
  3004. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3005. 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)
  3006. {
  3007. return expm1(arg, policies::policy<>());
  3008. }
  3009. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3010. 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)
  3011. {
  3012. return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
  3013. }
  3014. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3015. 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)
  3016. {
  3017. return lgamma(arg, sign, policies::policy<>());
  3018. }
  3019. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3020. 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)
  3021. {
  3022. return lgamma(arg, 0, pol);
  3023. }
  3024. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3025. 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)
  3026. {
  3027. return lgamma(arg, 0, policies::policy<>());
  3028. }
  3029. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3030. 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)
  3031. {
  3032. return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  3033. }
  3034. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3035. 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)
  3036. {
  3037. return tgamma(arg, policies::policy<>());
  3038. }
  3039. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3040. 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)
  3041. {
  3042. return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  3043. }
  3044. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3045. 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)
  3046. {
  3047. return log1p(arg, policies::policy<>());
  3048. }
  3049. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  3050. 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)
  3051. {
  3052. return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
  3053. }
  3054. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3055. 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)
  3056. {
  3057. return rsqrt(arg, policies::policy<>());
  3058. }
  3059. } // namespace math
  3060. } // namespace boost
  3061. namespace Eigen
  3062. {
  3063. template <class B1, class B2>
  3064. struct NumTraitsImp;
  3065. template <boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3066. struct NumTraitsImp<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>
  3067. {
  3068. using self_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>;
  3069. using Real = typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type;
  3070. using NonInteger = self_type; // Not correct but we can't do much better??
  3071. using Literal = double;
  3072. using Nested = self_type;
  3073. enum
  3074. {
  3075. IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
  3076. IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
  3077. ReadCost = 1,
  3078. AddCost = 4,
  3079. MulCost = 8,
  3080. IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
  3081. RequireInitialization = 1,
  3082. };
  3083. static Real epsilon()
  3084. {
  3085. #ifdef BOOST_MP_MATH_AVAILABLE
  3086. return boost::math::tools::epsilon< boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
  3087. #else
  3088. self_type result{1};
  3089. mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<self_type>::digits - 1, GMP_RNDN);
  3090. return result;
  3091. #endif
  3092. }
  3093. static Real dummy_precision()
  3094. {
  3095. return 1000 * epsilon();
  3096. }
  3097. static Real highest()
  3098. {
  3099. #ifdef BOOST_MP_MATH_AVAILABLE
  3100. return boost::math::tools::max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
  3101. #else
  3102. self_type value(0.5);
  3103. mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
  3104. return value;
  3105. #endif
  3106. }
  3107. static Real lowest()
  3108. {
  3109. #ifdef BOOST_MP_MATH_AVAILABLE
  3110. return boost::math::tools::min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
  3111. #else
  3112. return -(highest)();
  3113. #endif
  3114. }
  3115. static int digits10()
  3116. {
  3117. return Real::thread_default_precision();
  3118. }
  3119. static int digits()
  3120. {
  3121. return boost::math::tools::digits<Real>();
  3122. }
  3123. static int min_exponent()
  3124. {
  3125. return static_cast<int>(mpfr_get_emin());
  3126. }
  3127. static int max_exponent()
  3128. {
  3129. return static_cast<int>(mpfr_get_emax());
  3130. }
  3131. static Real infinity()
  3132. {
  3133. return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::infinity();
  3134. }
  3135. static Real quiet_NaN()
  3136. {
  3137. return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::quiet_NaN();
  3138. }
  3139. };
  3140. }
  3141. namespace std {
  3142. //
  3143. // numeric_limits [partial] specializations for the types declared in this header:
  3144. //
  3145. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3146. class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
  3147. {
  3148. using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
  3149. static number_type get_min()
  3150. {
  3151. number_type result{0.5};
  3152. mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
  3153. return result;
  3154. }
  3155. static number_type get_max()
  3156. {
  3157. number_type result{0.5};
  3158. mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
  3159. return result;
  3160. }
  3161. static number_type get_eps()
  3162. {
  3163. number_type result{1};
  3164. mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
  3165. return result;
  3166. }
  3167. public:
  3168. static constexpr bool is_specialized = true;
  3169. static number_type(min)()
  3170. {
  3171. static number_type value{get_min()};
  3172. return value;
  3173. }
  3174. static number_type(max)()
  3175. {
  3176. static number_type value{get_max()};
  3177. return value;
  3178. }
  3179. static constexpr number_type lowest()
  3180. {
  3181. return -(max)();
  3182. }
  3183. static constexpr int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
  3184. static constexpr int digits10 = Digits10;
  3185. // Is this really correct???
  3186. static constexpr int max_digits10 = static_cast<int>(boost::multiprecision::detail::calc_max_digits10<static_cast<unsigned>(digits)>::value);
  3187. static constexpr bool is_signed = true;
  3188. static constexpr bool is_integer = false;
  3189. static constexpr bool is_exact = false;
  3190. static constexpr int radix = 2;
  3191. static number_type epsilon()
  3192. {
  3193. static number_type value{get_eps()};
  3194. return value;
  3195. }
  3196. // What value should this be????
  3197. static number_type round_error()
  3198. {
  3199. // returns epsilon/2
  3200. return 0.5;
  3201. }
  3202. static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
  3203. static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
  3204. static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
  3205. static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
  3206. static constexpr bool has_infinity = true;
  3207. static constexpr bool has_quiet_NaN = true;
  3208. static constexpr bool has_signaling_NaN = false;
  3209. #ifdef _MSC_VER
  3210. #pragma warning(push)
  3211. #pragma warning(disable : 4996)
  3212. #endif
  3213. static constexpr float_denorm_style has_denorm = denorm_absent;
  3214. #ifdef _MSC_VER
  3215. #pragma warning(pop)
  3216. #endif
  3217. static constexpr bool has_denorm_loss = false;
  3218. static number_type infinity()
  3219. {
  3220. number_type value;
  3221. mpfr_set_inf(value.backend().data(), 1);
  3222. return value;
  3223. }
  3224. static number_type quiet_NaN()
  3225. {
  3226. number_type value;
  3227. mpfr_set_nan(value.backend().data());
  3228. return value;
  3229. }
  3230. static constexpr number_type signaling_NaN()
  3231. {
  3232. return number_type(0);
  3233. }
  3234. static constexpr number_type denorm_min() { return (min)(); }
  3235. static constexpr bool is_iec559 = false;
  3236. static constexpr bool is_bounded = true;
  3237. static constexpr bool is_modulo = false;
  3238. static constexpr bool traps = true;
  3239. static constexpr bool tinyness_before = false;
  3240. static constexpr float_round_style round_style = round_to_nearest;
  3241. };
  3242. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3243. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
  3244. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3245. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
  3246. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3247. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
  3248. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3249. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
  3250. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3251. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
  3252. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3253. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
  3254. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3255. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
  3256. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3257. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
  3258. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3259. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
  3260. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3261. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
  3262. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3263. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
  3264. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3265. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
  3266. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3267. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
  3268. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3269. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
  3270. #ifdef _MSC_VER
  3271. #pragma warning(push)
  3272. #pragma warning(disable : 4996)
  3273. #endif
  3274. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3275. constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
  3276. #ifdef _MSC_VER
  3277. #pragma warning(pop)
  3278. #endif
  3279. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3280. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
  3281. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3282. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
  3283. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3284. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
  3285. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3286. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
  3287. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3288. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
  3289. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3290. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
  3291. template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
  3292. constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
  3293. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3294. class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
  3295. {
  3296. using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates>;
  3297. public:
  3298. static constexpr bool is_specialized = false;
  3299. static number_type(min)()
  3300. {
  3301. number_type value(0.5);
  3302. mpfr_div_2exp(value.backend().data(), value.backend().data(), -mpfr_get_emin(), GMP_RNDN);
  3303. return value;
  3304. }
  3305. static number_type(max)()
  3306. {
  3307. number_type value(0.5);
  3308. mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
  3309. return value;
  3310. }
  3311. static number_type lowest()
  3312. {
  3313. return -(max)();
  3314. }
  3315. static constexpr int digits = INT_MAX;
  3316. static constexpr int digits10 = INT_MAX;
  3317. static constexpr int max_digits10 = INT_MAX;
  3318. static constexpr bool is_signed = true;
  3319. static constexpr bool is_integer = false;
  3320. static constexpr bool is_exact = false;
  3321. static constexpr int radix = 2;
  3322. static number_type epsilon()
  3323. {
  3324. number_type value(1);
  3325. mpfr_div_2exp(value.backend().data(), value.backend().data(), boost::multiprecision::detail::digits10_2_2(number_type::thread_default_precision()) - 1, GMP_RNDN);
  3326. return value;
  3327. }
  3328. static number_type round_error()
  3329. {
  3330. return 0.5;
  3331. }
  3332. static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
  3333. static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
  3334. static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
  3335. static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
  3336. static constexpr bool has_infinity = true;
  3337. static constexpr bool has_quiet_NaN = true;
  3338. static constexpr bool has_signaling_NaN = false;
  3339. #ifdef _MSC_VER
  3340. #pragma warning(push)
  3341. #pragma warning(disable : 4996)
  3342. #endif
  3343. static constexpr float_denorm_style has_denorm = denorm_absent;
  3344. #ifdef _MSC_VER
  3345. #pragma warning(pop)
  3346. #endif
  3347. static constexpr bool has_denorm_loss = false;
  3348. static number_type infinity()
  3349. {
  3350. number_type value;
  3351. mpfr_set_inf(value.backend().data(), 1);
  3352. return value;
  3353. }
  3354. static number_type quiet_NaN()
  3355. {
  3356. number_type value;
  3357. mpfr_set_nan(value.backend().data());
  3358. return value;
  3359. }
  3360. static number_type signaling_NaN() { return number_type(0); }
  3361. static number_type denorm_min() { return (min)(); }
  3362. static constexpr bool is_iec559 = false;
  3363. static constexpr bool is_bounded = true;
  3364. static constexpr bool is_modulo = false;
  3365. static constexpr bool traps = false;
  3366. static constexpr bool tinyness_before = false;
  3367. static constexpr float_round_style round_style = round_toward_zero;
  3368. };
  3369. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3370. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
  3371. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3372. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
  3373. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3374. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
  3375. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3376. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
  3377. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3378. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
  3379. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3380. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
  3381. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3382. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
  3383. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3384. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
  3385. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3386. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
  3387. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3388. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
  3389. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3390. constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
  3391. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3392. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
  3393. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3394. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
  3395. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3396. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
  3397. #ifdef _MSC_VER
  3398. #pragma warning(push)
  3399. #pragma warning(disable : 4996)
  3400. #endif
  3401. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3402. constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
  3403. #ifdef _MSC_VER
  3404. #pragma warning(pop)
  3405. #endif
  3406. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3407. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
  3408. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3409. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
  3410. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3411. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
  3412. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3413. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
  3414. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3415. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
  3416. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3417. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
  3418. template <boost::multiprecision::expression_template_option ExpressionTemplates>
  3419. constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;
  3420. } // namespace std
  3421. #endif