cpp_bin_float.hpp 105 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232
  1. ////////////////////////////////////////////////////////////////
  2. // Copyright 2013 - 2022 John Maddock.
  3. // Copyright 2022 Christopher Kormanyos.
  4. // Distributed under the Boost Software License,
  5. // Version 1.0. (See accompanying file LICENSE_1_0.txt
  6. // or copy at https://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_MP_CPP_BIN_FLOAT_HPP
  8. #define BOOST_MP_CPP_BIN_FLOAT_HPP
  9. #include <cmath>
  10. #include <cstdint>
  11. #include <limits>
  12. #include <type_traits>
  13. #include <boost/multiprecision/cpp_int.hpp>
  14. #include <boost/multiprecision/integer.hpp>
  15. #include <boost/multiprecision/detail/standalone_config.hpp>
  16. #include <boost/multiprecision/detail/fpclassify.hpp>
  17. #include <boost/multiprecision/detail/float_string_cvt.hpp>
  18. #include <boost/multiprecision/traits/max_digits10.hpp>
  19. #include <boost/multiprecision/detail/hash.hpp>
  20. #include <boost/multiprecision/detail/no_exceptions_support.hpp>
  21. #include <boost/multiprecision/detail/assert.hpp>
  22. #include <boost/multiprecision/detail/float128_functions.hpp>
  23. #include <boost/multiprecision/detail/functions/trunc.hpp>
  24. //
  25. // Some includes we need from Boost.Math, since we rely on that library to provide these functions:
  26. //
  27. #ifdef BOOST_MP_MATH_AVAILABLE
  28. #include <boost/math/special_functions/asinh.hpp>
  29. #include <boost/math/special_functions/acosh.hpp>
  30. #include <boost/math/special_functions/atanh.hpp>
  31. #include <boost/math/special_functions/cbrt.hpp>
  32. #include <boost/math/special_functions/expm1.hpp>
  33. #include <boost/math/special_functions/gamma.hpp>
  34. #endif
  35. #ifdef BOOST_HAS_FLOAT128
  36. #include <quadmath.h>
  37. #endif
  38. namespace boost {
  39. namespace multiprecision {
  40. namespace backends {
  41. #ifdef BOOST_MSVC
  42. #pragma warning(push)
  43. #pragma warning(disable : 4522 6326) // multiple assignment operators specified, comparison of two constants
  44. #endif
  45. namespace detail {
  46. template <class U>
  47. inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value, bool>::type is_negative(U) { return false; }
  48. template <class S>
  49. inline typename std::enable_if< !boost::multiprecision::detail::is_unsigned<S>::value, bool>::type is_negative(S s) { return s < 0; }
  50. template <class Float, std::ptrdiff_t, bool = number_category<Float>::value == number_kind_floating_point>
  51. struct is_cpp_bin_float_implicitly_constructible_from_type
  52. {
  53. static constexpr bool value = false;
  54. };
  55. template <class Float, std::ptrdiff_t bit_count>
  56. struct is_cpp_bin_float_implicitly_constructible_from_type<Float, bit_count, true>
  57. {
  58. static constexpr bool value = (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count)) && (std::numeric_limits<Float>::radix == 2) && std::numeric_limits<Float>::is_specialized
  59. #ifdef BOOST_HAS_FLOAT128
  60. && !std::is_same<Float, float128_type>::value
  61. #endif
  62. && (std::is_floating_point<Float>::value || is_number<Float>::value);
  63. };
  64. template <class Float, std::ptrdiff_t, bool = number_category<Float>::value == number_kind_floating_point>
  65. struct is_cpp_bin_float_explicitly_constructible_from_type
  66. {
  67. static constexpr bool value = false;
  68. };
  69. template <class Float, std::ptrdiff_t bit_count>
  70. struct is_cpp_bin_float_explicitly_constructible_from_type<Float, bit_count, true>
  71. {
  72. static constexpr bool value = (std::numeric_limits<Float>::digits > static_cast<int>(bit_count)) && (std::numeric_limits<Float>::radix == 2) && std::numeric_limits<Float>::is_specialized
  73. #ifdef BOOST_HAS_FLOAT128
  74. && !std::is_same<Float, float128_type>::value
  75. #endif
  76. ;
  77. };
  78. } // namespace detail
  79. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
  80. class cpp_bin_float
  81. {
  82. public:
  83. static constexpr unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + (((Digits * 1000uL) % 301) ? 2u : 1u);
  84. using rep_type = cpp_int_backend<std::is_void<Allocator>::value ? bit_count : 0, bit_count, std::is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator>;
  85. using double_rep_type = cpp_int_backend<std::is_void<Allocator>::value ? 2 * bit_count : 0, 2 * bit_count, std::is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator>;
  86. using signed_types = typename rep_type::signed_types;
  87. using unsigned_types = typename rep_type::unsigned_types;
  88. using float_types = std::tuple<float, double, long double>;
  89. using exponent_type = Exponent;
  90. static constexpr exponent_type max_exponent_limit = (std::numeric_limits<exponent_type>::max)()- 2 * static_cast<exponent_type>(bit_count);
  91. static constexpr exponent_type min_exponent_limit = (std::numeric_limits<exponent_type>::min)() + 2 * static_cast<exponent_type>(bit_count);
  92. static_assert(MinExponent >= min_exponent_limit, "Template parameter MinExponent is too negative for our internal logic to function correctly, sorry!");
  93. static_assert(MaxExponent <= max_exponent_limit, "Template parameter MaxExponent is too large for our internal logic to function correctly, sorry!");
  94. static_assert(MinExponent <= 0, "Template parameter MinExponent can not be positive!");
  95. static_assert(MaxExponent >= 0, "Template parameter MaxExponent can not be negative!");
  96. static constexpr exponent_type max_exponent = MaxExponent == 0 ? max_exponent_limit : MaxExponent;
  97. static constexpr exponent_type min_exponent = MinExponent == 0 ? min_exponent_limit : MinExponent;
  98. static constexpr exponent_type exponent_zero = max_exponent + 1;
  99. static constexpr exponent_type exponent_infinity = max_exponent + 2;
  100. static constexpr exponent_type exponent_nan = max_exponent + 3;
  101. private:
  102. rep_type m_data;
  103. exponent_type m_exponent;
  104. bool m_sign;
  105. public:
  106. cpp_bin_float() noexcept(noexcept(rep_type())) : m_data(), m_exponent(exponent_zero), m_sign(false) {}
  107. cpp_bin_float(const cpp_bin_float& o) noexcept(noexcept(rep_type(std::declval<const rep_type&>())))
  108. : m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {}
  109. template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
  110. cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE>& o, typename std::enable_if<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)
  111. {
  112. *this = o;
  113. }
  114. template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
  115. explicit cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE>& o, typename std::enable_if< !(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)
  116. : m_exponent(o.exponent()), m_sign(o.sign())
  117. {
  118. *this = o;
  119. }
  120. // rvalue copy:
  121. template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
  122. cpp_bin_float(cpp_bin_float<D, B, A, E, MinE, MaxE>&& o, typename std::enable_if<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)noexcept(noexcept(rep_type(std::declval<rep_type&&>())))
  123. {
  124. *this = std::move(o);
  125. }
  126. template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
  127. explicit cpp_bin_float(cpp_bin_float<D, B, A, E, MinE, MaxE>&& o, typename std::enable_if< !(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr) noexcept(noexcept(rep_type(std::declval<rep_type&&>())))
  128. : m_exponent(o.exponent()), m_sign(o.sign())
  129. {
  130. *this = std::move(o);
  131. }
  132. template <class Float>
  133. cpp_bin_float(const Float& f,
  134. typename std::enable_if<detail::is_cpp_bin_float_implicitly_constructible_from_type<Float, static_cast<std::ptrdiff_t>(bit_count)>::value>::type const* = nullptr)
  135. : m_data(), m_exponent(0), m_sign(false)
  136. {
  137. this->assign_float(f);
  138. }
  139. template <class Float>
  140. explicit cpp_bin_float(const Float& f,
  141. typename std::enable_if<detail::is_cpp_bin_float_explicitly_constructible_from_type<Float, static_cast<std::ptrdiff_t>(bit_count)>::value>::type const* = nullptr)
  142. : m_data(), m_exponent(0), m_sign(false)
  143. {
  144. this->assign_float(f);
  145. }
  146. #ifdef BOOST_HAS_FLOAT128
  147. template <class Float>
  148. cpp_bin_float(const Float& f,
  149. typename std::enable_if<
  150. std::is_same<Float, float128_type>::value && (static_cast<int>(bit_count) >= 113)>::type const* = nullptr)
  151. : m_data(), m_exponent(0), m_sign(false)
  152. {
  153. this->assign_float(f);
  154. }
  155. template <class Float>
  156. explicit cpp_bin_float(const Float& f,
  157. typename std::enable_if<
  158. std::is_same<Float, float128_type>::value && (static_cast<int>(bit_count) < 113)>::type const* = nullptr)
  159. : m_data(), m_exponent(0), m_sign(false)
  160. {
  161. this->assign_float(f);
  162. }
  163. #endif
  164. cpp_bin_float& operator=(const cpp_bin_float& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
  165. {
  166. m_data = o.m_data;
  167. m_exponent = o.m_exponent;
  168. m_sign = o.m_sign;
  169. return *this;
  170. }
  171. template <class A, class E, E MinE, E MaxE>
  172. cpp_bin_float& operator=(const cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
  173. {
  174. m_data = o.bits();
  175. m_sign = o.sign();
  176. if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_zero)
  177. m_exponent = exponent_zero;
  178. else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_nan)
  179. m_exponent = exponent_nan;
  180. else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_infinity)
  181. m_exponent = exponent_infinity;
  182. else if (o.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
  183. {
  184. // Overflow:
  185. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
  186. bits() = static_cast<limb_type>(0u);
  187. }
  188. else if (o.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
  189. {
  190. // Underflow:
  191. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  192. bits() = static_cast<limb_type>(0u);
  193. }
  194. else
  195. m_exponent = o.exponent();
  196. return *this;
  197. }
  198. // rvalue copy:
  199. template <class A, class E, E MinE, E MaxE>
  200. cpp_bin_float& operator=(cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>&& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<rep_type&&>()))
  201. {
  202. m_data = std::move(o.bits());
  203. m_sign = o.sign();
  204. if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_zero)
  205. m_exponent = exponent_zero;
  206. else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_nan)
  207. m_exponent = exponent_nan;
  208. else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_infinity)
  209. m_exponent = exponent_infinity;
  210. else if (o.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
  211. {
  212. // Overflow:
  213. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
  214. bits() = static_cast<limb_type>(0u);
  215. }
  216. else if (o.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
  217. {
  218. // Underflow:
  219. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  220. bits() = static_cast<limb_type>(0u);
  221. }
  222. else
  223. m_exponent = o.exponent();
  224. return *this;
  225. }
  226. template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
  227. cpp_bin_float& operator=(const cpp_bin_float<D, B, A, E, MinE, MaxE>& f)
  228. {
  229. switch (eval_fpclassify(f))
  230. {
  231. case FP_ZERO:
  232. m_data = limb_type(0);
  233. m_sign = f.sign();
  234. m_exponent = exponent_zero;
  235. break;
  236. case FP_NAN:
  237. m_data = limb_type(0);
  238. m_sign = false;
  239. m_exponent = exponent_nan;
  240. break;
  241. ;
  242. case FP_INFINITE:
  243. m_data = limb_type(0);
  244. m_sign = f.sign();
  245. m_exponent = exponent_infinity;
  246. break;
  247. default:
  248. typename cpp_bin_float<D, B, A, E, MinE, MaxE>::rep_type b(f.bits());
  249. this->exponent() = f.exponent() + (E)bit_count - (E)cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count;
  250. this->sign() = f.sign();
  251. copy_and_round(*this, b);
  252. }
  253. return *this;
  254. }
  255. #ifdef BOOST_HAS_FLOAT128
  256. template <class Float>
  257. typename std::enable_if<
  258. (number_category<Float>::value == number_kind_floating_point)
  259. //&& (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count))
  260. && ((std::numeric_limits<Float>::radix == 2) || (std::is_same<Float, float128_type>::value)),
  261. cpp_bin_float&>::type
  262. operator=(const Float& f)
  263. #else
  264. template <class Float>
  265. typename std::enable_if<
  266. (number_category<Float>::value == number_kind_floating_point)
  267. //&& (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count))
  268. && (std::numeric_limits<Float>::radix == 2),
  269. cpp_bin_float&>::type
  270. operator=(const Float& f)
  271. #endif
  272. {
  273. return assign_float(f);
  274. }
  275. #ifdef BOOST_HAS_FLOAT128
  276. template <class Float>
  277. typename std::enable_if<std::is_same<Float, float128_type>::value, cpp_bin_float&>::type assign_float(Float f)
  278. {
  279. using default_ops::eval_add;
  280. using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
  281. if (f == 0)
  282. {
  283. m_data = limb_type(0);
  284. m_sign = (signbitq(f) > 0);
  285. m_exponent = exponent_zero;
  286. return *this;
  287. }
  288. else if (isnanq(f))
  289. {
  290. m_data = limb_type(0);
  291. m_sign = false;
  292. m_exponent = exponent_nan;
  293. return *this;
  294. }
  295. else if (isinfq(f))
  296. {
  297. m_data = limb_type(0);
  298. m_sign = (f < 0);
  299. m_exponent = exponent_infinity;
  300. return *this;
  301. }
  302. if (f < 0)
  303. {
  304. *this = -f;
  305. this->negate();
  306. return *this;
  307. }
  308. using ui_type = typename std::tuple_element<0, unsigned_types>::type;
  309. m_data = static_cast<ui_type>(0u);
  310. m_sign = false;
  311. m_exponent = 0;
  312. constexpr std::ptrdiff_t bits = sizeof(int) * CHAR_BIT - 1;
  313. int e;
  314. f = frexpq(f, &e);
  315. while (f)
  316. {
  317. f = ldexpq(f, bits);
  318. e -= bits;
  319. int ipart = static_cast<int>(truncq(f));
  320. f -= ipart;
  321. m_exponent += bits;
  322. cpp_bin_float t;
  323. t = static_cast<bf_int_type>(ipart);
  324. eval_add(*this, t);
  325. }
  326. m_exponent += static_cast<Exponent>(e);
  327. return *this;
  328. }
  329. #endif
  330. #ifdef BOOST_HAS_FLOAT128
  331. template <class Float>
  332. typename std::enable_if<std::is_floating_point<Float>::value && !std::is_same<Float, float128_type>::value, cpp_bin_float&>::type assign_float(Float f)
  333. #else
  334. template <class Float>
  335. typename std::enable_if<std::is_floating_point<Float>::value, cpp_bin_float&>::type assign_float(Float f)
  336. #endif
  337. {
  338. using std::frexp;
  339. using std::ldexp;
  340. using std::signbit;
  341. using default_ops::eval_add;
  342. using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
  343. switch (BOOST_MP_FPCLASSIFY(f))
  344. {
  345. case FP_ZERO:
  346. m_data = limb_type(0);
  347. m_sign = ((signbit)(f));
  348. m_exponent = exponent_zero;
  349. return *this;
  350. case FP_NAN:
  351. m_data = limb_type(0);
  352. m_sign = false;
  353. m_exponent = exponent_nan;
  354. return *this;
  355. case FP_INFINITE:
  356. m_data = limb_type(0);
  357. m_sign = (f < 0);
  358. m_exponent = exponent_infinity;
  359. return *this;
  360. }
  361. if (f < 0)
  362. {
  363. *this = -f;
  364. this->negate();
  365. return *this;
  366. }
  367. using ui_type = typename std::tuple_element<0, unsigned_types>::type;
  368. m_data = static_cast<ui_type>(0u);
  369. m_sign = false;
  370. m_exponent = 0;
  371. constexpr std::ptrdiff_t bits = sizeof(int) * CHAR_BIT - 1;
  372. int e;
  373. f = frexp(f, &e);
  374. while (f != static_cast<Float>(0.0F))
  375. {
  376. f = ldexp(f, bits);
  377. e -= static_cast<int>(bits);
  378. int ipart = boost::multiprecision::detail::itrunc(f);
  379. f -= static_cast<Float>(ipart);
  380. m_exponent += static_cast<exponent_type>(bits);
  381. cpp_bin_float t;
  382. t = static_cast<bf_int_type>(ipart);
  383. eval_add(*this, t);
  384. }
  385. m_exponent += static_cast<Exponent>(e);
  386. return *this;
  387. }
  388. template <class Float>
  389. typename std::enable_if<
  390. (number_category<Float>::value == number_kind_floating_point) && !std::is_floating_point<Float>::value && (number_category<Float>::value == number_kind_floating_point),
  391. cpp_bin_float&>::type
  392. assign_float(Float f)
  393. {
  394. using default_ops::eval_add;
  395. using default_ops::eval_convert_to;
  396. using default_ops::eval_get_sign;
  397. using default_ops::eval_subtract;
  398. using f_int_type = typename boost::multiprecision::detail::canonical<int, Float>::type ;
  399. using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
  400. switch (eval_fpclassify(f))
  401. {
  402. case FP_ZERO:
  403. m_data = limb_type(0);
  404. m_sign = (eval_get_sign(f) > 0);
  405. m_exponent = exponent_zero;
  406. return *this;
  407. case FP_NAN:
  408. m_data = limb_type(0);
  409. m_sign = false;
  410. m_exponent = exponent_nan;
  411. return *this;
  412. case FP_INFINITE:
  413. m_data = limb_type(0);
  414. m_sign = eval_get_sign(f) < 0;
  415. m_exponent = exponent_infinity;
  416. return *this;
  417. }
  418. if (eval_get_sign(f) < 0)
  419. {
  420. f.negate();
  421. assign_float(f);
  422. this->negate();
  423. return *this;
  424. }
  425. using ui_type = typename std::tuple_element<0, unsigned_types>::type;
  426. m_data = static_cast<ui_type>(0u);
  427. m_sign = false;
  428. m_exponent = 0;
  429. constexpr std::ptrdiff_t bits = sizeof(int) * CHAR_BIT - 1;
  430. int e;
  431. eval_frexp(f, f, &e);
  432. while (eval_get_sign(f) != 0)
  433. {
  434. eval_ldexp(f, f, bits);
  435. e -= bits;
  436. int ipart;
  437. eval_convert_to(&ipart, f);
  438. eval_subtract(f, static_cast<f_int_type>(ipart));
  439. m_exponent += bits;
  440. eval_add(*this, static_cast<bf_int_type>(ipart));
  441. }
  442. m_exponent += e;
  443. if (m_exponent > max_exponent)
  444. m_exponent = exponent_infinity;
  445. if (m_exponent < min_exponent)
  446. {
  447. m_data = limb_type(0u);
  448. m_exponent = exponent_zero;
  449. m_sign = (eval_get_sign(f) > 0);
  450. }
  451. else if (eval_get_sign(m_data) == 0)
  452. {
  453. m_exponent = exponent_zero;
  454. m_sign = (eval_get_sign(f) > 0);
  455. }
  456. return *this;
  457. }
  458. template <class B, expression_template_option et>
  459. cpp_bin_float& assign_float(const number<B, et>& f)
  460. {
  461. return assign_float(f.backend());
  462. }
  463. template <class I>
  464. typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value, cpp_bin_float&>::type operator=(const I& i)
  465. {
  466. using default_ops::eval_bit_test;
  467. if (!i)
  468. {
  469. m_data = static_cast<limb_type>(0);
  470. m_exponent = exponent_zero;
  471. m_sign = false;
  472. }
  473. else
  474. {
  475. using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type ;
  476. ui_type fi = static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(i));
  477. using ar_type = typename boost::multiprecision::detail::canonical<ui_type, rep_type>::type;
  478. m_data = static_cast<ar_type>(fi);
  479. std::size_t shift = msb(fi);
  480. if (shift >= bit_count)
  481. {
  482. m_exponent = static_cast<Exponent>(shift);
  483. m_data = static_cast<ar_type>(fi >> (shift + 1 - bit_count));
  484. }
  485. else
  486. {
  487. m_exponent = static_cast<Exponent>(shift);
  488. eval_left_shift(m_data, bit_count - shift - 1);
  489. }
  490. BOOST_MP_ASSERT(eval_bit_test(m_data, bit_count - 1));
  491. m_sign = detail::is_negative(i);
  492. }
  493. return *this;
  494. }
  495. cpp_bin_float& operator=(const char* s);
  496. void swap(cpp_bin_float& o) noexcept
  497. {
  498. m_data.swap(o.m_data);
  499. std::swap(m_exponent, o.m_exponent);
  500. std::swap(m_sign, o.m_sign);
  501. }
  502. std::string str(std::streamsize dig, std::ios_base::fmtflags f) const;
  503. void negate()
  504. {
  505. if (m_exponent != exponent_nan)
  506. m_sign = !m_sign;
  507. }
  508. int compare(const cpp_bin_float& o) const noexcept
  509. {
  510. if (m_sign != o.m_sign)
  511. return (m_exponent == exponent_zero) && (m_exponent == o.m_exponent) ? 0 : m_sign ? -1 : 1;
  512. int result;
  513. if (m_exponent == exponent_nan)
  514. return -1;
  515. else if (m_exponent != o.m_exponent)
  516. {
  517. if (m_exponent == exponent_zero)
  518. result = -1;
  519. else if (o.m_exponent == exponent_zero)
  520. result = 1;
  521. else
  522. result = m_exponent > o.m_exponent ? 1 : -1;
  523. }
  524. else
  525. result = m_data.compare(o.m_data);
  526. if (m_sign)
  527. result = -result;
  528. return result;
  529. }
  530. template <class A>
  531. int compare(const A& o) const noexcept
  532. {
  533. cpp_bin_float b;
  534. b = o;
  535. return compare(b);
  536. }
  537. rep_type& bits() { return m_data; }
  538. const rep_type& bits() const { return m_data; }
  539. exponent_type& exponent() { return m_exponent; }
  540. const exponent_type& exponent() const { return m_exponent; }
  541. bool& sign() { return m_sign; }
  542. const bool& sign() const { return m_sign; }
  543. void check_invariants()
  544. {
  545. using default_ops::eval_bit_test;
  546. using default_ops::eval_is_zero;
  547. if ((m_exponent <= max_exponent) && (m_exponent >= min_exponent))
  548. {
  549. BOOST_MP_ASSERT(eval_bit_test(m_data, bit_count - 1));
  550. }
  551. else
  552. {
  553. BOOST_MP_ASSERT(m_exponent > max_exponent);
  554. BOOST_MP_ASSERT(m_exponent <= exponent_nan);
  555. BOOST_MP_ASSERT(eval_is_zero(m_data));
  556. }
  557. }
  558. #ifndef BOOST_MP_STANDALONE
  559. template <class Archive>
  560. void serialize(Archive& ar, const unsigned int /*version*/)
  561. {
  562. ar& boost::make_nvp("data", m_data);
  563. ar& boost::make_nvp("exponent", m_exponent);
  564. ar& boost::make_nvp("sign", m_sign);
  565. }
  566. #endif
  567. };
  568. #ifdef BOOST_MSVC
  569. #pragma warning(pop)
  570. #endif
  571. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Int>
  572. inline void copy_and_round(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, Int& arg, std::ptrdiff_t bits_to_keep = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
  573. {
  574. // Precondition: exponent of res must have been set before this function is called
  575. // as we may need to adjust it based on how many bits_to_keep in arg are set.
  576. using default_ops::eval_bit_test;
  577. using default_ops::eval_get_sign;
  578. using default_ops::eval_increment;
  579. using default_ops::eval_left_shift;
  580. using default_ops::eval_lsb;
  581. using default_ops::eval_msb;
  582. using default_ops::eval_right_shift;
  583. // cancellation may have resulted in arg being all zeros:
  584. if (eval_get_sign(arg) == 0)
  585. {
  586. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  587. res.sign() = false;
  588. res.bits() = static_cast<limb_type>(0u);
  589. return;
  590. }
  591. std::ptrdiff_t msb = static_cast<std::ptrdiff_t>(eval_msb(arg));
  592. if (static_cast<std::ptrdiff_t >(bits_to_keep) > msb + 1)
  593. {
  594. // Must have had cancellation in subtraction,
  595. // or be converting from a narrower type, so shift left:
  596. res.bits() = arg;
  597. eval_left_shift(res.bits(), static_cast<double_limb_type>(bits_to_keep - msb - 1));
  598. res.exponent() -= static_cast<Exponent>(bits_to_keep - msb - 1);
  599. }
  600. else if (static_cast<std::ptrdiff_t >(bits_to_keep) < msb + 1)
  601. {
  602. // We have more bits_to_keep than we need, so round as required,
  603. // first get the rounding bit:
  604. bool roundup = eval_bit_test(arg, static_cast<std::size_t>(msb - bits_to_keep));
  605. // Then check for a tie:
  606. if (roundup && (msb - bits_to_keep == static_cast<std::ptrdiff_t>(eval_lsb(arg))))
  607. {
  608. // Ties round towards even:
  609. if (!eval_bit_test(arg, static_cast<std::size_t>(msb - bits_to_keep + 1)))
  610. roundup = false;
  611. }
  612. // Shift off the bits_to_keep we don't need:
  613. eval_right_shift(arg, static_cast<double_limb_type>(msb - bits_to_keep + 1));
  614. res.exponent() += static_cast<Exponent>(msb - bits_to_keep + 1);
  615. if (roundup)
  616. {
  617. eval_increment(arg);
  618. if (bits_to_keep)
  619. {
  620. if (eval_bit_test(arg, static_cast<std::size_t>(bits_to_keep)))
  621. {
  622. // This happens very very rairly, all the bits left after
  623. // truncation must be 1's and we're rounding up an order of magnitude:
  624. eval_right_shift(arg, 1u);
  625. ++res.exponent();
  626. }
  627. }
  628. else
  629. {
  630. // We get here when bits_to_keep is zero but we're rounding up,
  631. // as a result we end up with a single digit that is a 1:
  632. ++bits_to_keep;
  633. }
  634. }
  635. if (bits_to_keep != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
  636. {
  637. // Normalize result when we're rounding to fewer bits than we can hold, only happens in conversions
  638. // to narrower types:
  639. eval_left_shift(arg, static_cast<double_limb_type>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - bits_to_keep));
  640. res.exponent() -= static_cast<Exponent>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - bits_to_keep);
  641. }
  642. res.bits() = arg;
  643. }
  644. else
  645. {
  646. res.bits() = arg;
  647. }
  648. if (!bits_to_keep && !res.bits().limbs()[0])
  649. {
  650. // We're keeping zero bits and did not round up, so result is zero:
  651. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  652. return;
  653. }
  654. // Result must be normalized:
  655. BOOST_MP_ASSERT(((std::ptrdiff_t )eval_msb(res.bits()) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
  656. if (res.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
  657. {
  658. // Overflow:
  659. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
  660. res.bits() = static_cast<limb_type>(0u);
  661. }
  662. else if (res.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
  663. {
  664. // Underflow:
  665. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  666. res.bits() = static_cast<limb_type>(0u);
  667. }
  668. }
  669. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class BinFloat2, class BinFloat3>
  670. inline void do_eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  671. const BinFloat2& a, const BinFloat3& b)
  672. {
  673. if (a.exponent() < b.exponent())
  674. {
  675. bool s = a.sign();
  676. do_eval_add(res, b, a);
  677. if (res.sign() != s)
  678. res.negate();
  679. return;
  680. }
  681. using default_ops::eval_add;
  682. using default_ops::eval_bit_test;
  683. using exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
  684. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
  685. // Special cases first:
  686. switch (a.exponent())
  687. {
  688. case BinFloat2::exponent_zero:
  689. {
  690. bool s = a.sign();
  691. res = b;
  692. res.sign() = s;
  693. return;
  694. }
  695. case BinFloat2::exponent_infinity:
  696. if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
  697. res = b;
  698. else
  699. res = a;
  700. return; // result is still infinite.
  701. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  702. res = a;
  703. return; // result is still a NaN.
  704. }
  705. switch (b.exponent())
  706. {
  707. case BinFloat3::exponent_zero:
  708. res = a;
  709. return;
  710. case BinFloat3::exponent_infinity:
  711. res = b;
  712. if (res.sign())
  713. res.negate();
  714. return; // result is infinite.
  715. case BinFloat3::exponent_nan:
  716. res = b;
  717. return; // result is a NaN.
  718. }
  719. static_assert((std::numeric_limits<exponent_type>::max)() - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent, "Exponent range check failed");
  720. bool s = a.sign();
  721. dt = a.bits();
  722. if (a.exponent() > (std::ptrdiff_t )cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + b.exponent())
  723. {
  724. res.exponent() = a.exponent();
  725. }
  726. else
  727. {
  728. exponent_type e_diff = a.exponent() - b.exponent();
  729. BOOST_MP_ASSERT(e_diff >= 0);
  730. eval_left_shift(dt, static_cast<double_limb_type>(e_diff));
  731. res.exponent() = a.exponent() - e_diff;
  732. eval_add(dt, b.bits());
  733. }
  734. copy_and_round(res, dt);
  735. res.check_invariants();
  736. if (res.sign() != s)
  737. res.negate();
  738. }
  739. template <class BinFloat1, class BinFloat2, class BinFloat3>
  740. inline void do_eval_subtract(BinFloat1& res, const BinFloat2& a, const BinFloat3& b)
  741. {
  742. using default_ops::eval_bit_test;
  743. using default_ops::eval_decrement;
  744. using default_ops::eval_subtract;
  745. typename BinFloat1::double_rep_type dt;
  746. // Special cases first:
  747. switch (a.exponent())
  748. {
  749. case BinFloat2::exponent_zero:
  750. if (b.exponent() == BinFloat3::exponent_nan)
  751. res = std::numeric_limits<number<BinFloat1> >::quiet_NaN().backend();
  752. else
  753. {
  754. bool s = a.sign();
  755. res = b;
  756. if (res.exponent() == BinFloat1::exponent_zero)
  757. res.sign() = false;
  758. else if (res.sign() == s)
  759. res.negate();
  760. }
  761. return;
  762. case BinFloat2::exponent_infinity:
  763. if ((b.exponent() == BinFloat3::exponent_nan) || (b.exponent() == BinFloat3::exponent_infinity))
  764. res = std::numeric_limits<number<BinFloat1> >::quiet_NaN().backend();
  765. else
  766. res = a;
  767. return;
  768. case BinFloat2::exponent_nan:
  769. res = a;
  770. return; // result is still a NaN.
  771. }
  772. switch (b.exponent())
  773. {
  774. case BinFloat3::exponent_zero:
  775. res = a;
  776. return;
  777. case BinFloat3::exponent_infinity:
  778. res.exponent() = BinFloat1::exponent_infinity;
  779. res.sign() = !a.sign();
  780. res.bits() = static_cast<limb_type>(0u);
  781. return; // result is a NaN.
  782. case BinFloat3::exponent_nan:
  783. res = b;
  784. return; // result is still a NaN.
  785. }
  786. bool s = a.sign();
  787. if ((a.exponent() > b.exponent()) || ((a.exponent() == b.exponent()) && a.bits().compare(b.bits()) >= 0))
  788. {
  789. dt = a.bits();
  790. if (a.exponent() <= (std::ptrdiff_t )BinFloat1::bit_count + b.exponent())
  791. {
  792. typename BinFloat1::exponent_type e_diff = a.exponent() - b.exponent();
  793. eval_left_shift(dt, static_cast<double_limb_type>(e_diff));
  794. res.exponent() = a.exponent() - e_diff;
  795. eval_subtract(dt, b.bits());
  796. }
  797. else if (a.exponent() == (std::ptrdiff_t )BinFloat1::bit_count + b.exponent() + 1)
  798. {
  799. if ((eval_lsb(a.bits()) == BinFloat1::bit_count - 1)
  800. && (eval_lsb(b.bits()) != BinFloat1::bit_count - 1))
  801. {
  802. eval_left_shift(dt, 1);
  803. eval_decrement(dt);
  804. res.exponent() = a.exponent() - 1;
  805. }
  806. else
  807. res.exponent() = a.exponent();
  808. }
  809. else
  810. res.exponent() = a.exponent();
  811. }
  812. else
  813. {
  814. dt = b.bits();
  815. if (b.exponent() <= (std::ptrdiff_t )BinFloat1::bit_count + a.exponent())
  816. {
  817. typename BinFloat1::exponent_type e_diff = a.exponent() - b.exponent();
  818. eval_left_shift(dt, static_cast<double_limb_type>(-e_diff));
  819. res.exponent() = b.exponent() + e_diff;
  820. eval_subtract(dt, a.bits());
  821. }
  822. else if (b.exponent() == (std::ptrdiff_t )BinFloat1::bit_count + a.exponent() + 1)
  823. {
  824. if ((eval_lsb(a.bits()) != BinFloat1::bit_count - 1)
  825. && eval_lsb(b.bits()))
  826. {
  827. eval_left_shift(dt, 1);
  828. eval_decrement(dt);
  829. res.exponent() = b.exponent() - 1;
  830. }
  831. else
  832. res.exponent() = b.exponent();
  833. }
  834. else
  835. res.exponent() = b.exponent();
  836. s = !s;
  837. }
  838. copy_and_round(res, dt);
  839. if (res.exponent() == BinFloat1::exponent_zero)
  840. res.sign() = false;
  841. else if (res.sign() != s)
  842. res.negate();
  843. res.check_invariants();
  844. }
  845. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  846. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
  847. class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
  848. inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  849. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a,
  850. const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
  851. {
  852. if (a.sign() == b.sign())
  853. do_eval_add(res, a, b);
  854. else
  855. do_eval_subtract(res, a, b);
  856. }
  857. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  858. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
  859. inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  860. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
  861. {
  862. return eval_add(res, res, a);
  863. }
  864. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  865. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
  866. class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
  867. inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  868. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a,
  869. const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
  870. {
  871. if (a.sign() != b.sign())
  872. do_eval_add(res, a, b);
  873. else
  874. do_eval_subtract(res, a, b);
  875. }
  876. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  877. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
  878. inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  879. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
  880. {
  881. return eval_subtract(res, res, a);
  882. }
  883. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  884. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
  885. class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
  886. inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  887. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a,
  888. const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
  889. {
  890. using default_ops::eval_bit_test;
  891. using default_ops::eval_multiply;
  892. // Special cases first:
  893. switch (a.exponent())
  894. {
  895. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
  896. {
  897. if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan)
  898. res = b;
  899. else if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity)
  900. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  901. else
  902. {
  903. bool s = a.sign() != b.sign();
  904. res = a;
  905. res.sign() = s;
  906. }
  907. return;
  908. }
  909. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
  910. switch (b.exponent())
  911. {
  912. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
  913. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  914. break;
  915. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
  916. res = b;
  917. break;
  918. default:
  919. bool s = a.sign() != b.sign();
  920. res = a;
  921. res.sign() = s;
  922. break;
  923. }
  924. return;
  925. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
  926. res = a;
  927. return;
  928. }
  929. if (b.exponent() > cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::max_exponent)
  930. {
  931. bool s = a.sign() != b.sign();
  932. res = b;
  933. res.sign() = s;
  934. return;
  935. }
  936. if ((a.exponent() > 0) && (b.exponent() > 0))
  937. {
  938. if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + 2 - a.exponent() < b.exponent())
  939. {
  940. // We will certainly overflow:
  941. bool s = a.sign() != b.sign();
  942. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
  943. res.sign() = s;
  944. res.bits() = static_cast<limb_type>(0u);
  945. return;
  946. }
  947. }
  948. if ((a.exponent() < 0) && (b.exponent() < 0))
  949. {
  950. if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - 2 - a.exponent() > b.exponent())
  951. {
  952. // We will certainly underflow:
  953. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  954. res.sign() = a.sign() != b.sign();
  955. res.bits() = static_cast<limb_type>(0u);
  956. return;
  957. }
  958. }
  959. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
  960. eval_multiply(dt, a.bits(), b.bits());
  961. res.exponent() = a.exponent() + b.exponent() - (Exponent)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
  962. copy_and_round(res, dt);
  963. res.check_invariants();
  964. res.sign() = a.sign() != b.sign();
  965. }
  966. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  967. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
  968. inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  969. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
  970. {
  971. eval_multiply(res, res, a);
  972. }
  973. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  974. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class U>
  975. inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  976. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, const U& b)
  977. {
  978. using default_ops::eval_bit_test;
  979. using default_ops::eval_multiply;
  980. bool s = a.sign(); // saved for later in case a and res are the same object.
  981. // Special cases first:
  982. switch (a.exponent())
  983. {
  984. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
  985. {
  986. res = a;
  987. res.sign() = s;
  988. return;
  989. }
  990. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
  991. if (b == 0)
  992. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  993. else
  994. res = a;
  995. return;
  996. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
  997. res = a;
  998. return;
  999. }
  1000. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
  1001. using canon_ui_type = typename boost::multiprecision::detail::canonical<U, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::type;
  1002. eval_multiply(dt, a.bits(), static_cast<canon_ui_type>(b));
  1003. res.exponent() = a.exponent();
  1004. copy_and_round(res, dt);
  1005. res.check_invariants();
  1006. res.sign() = s;
  1007. }
  1008. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
  1009. inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const U& b)
  1010. {
  1011. eval_multiply(res, res, b);
  1012. }
  1013. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  1014. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class S>
  1015. inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  1016. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, const S& b)
  1017. {
  1018. using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type;
  1019. eval_multiply(res, a, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(b)));
  1020. if (b < 0)
  1021. res.negate();
  1022. }
  1023. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
  1024. inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const S& b)
  1025. {
  1026. eval_multiply(res, res, b);
  1027. }
  1028. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  1029. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
  1030. class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
  1031. inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  1032. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u,
  1033. const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& v)
  1034. {
  1035. #ifdef BOOST_MSVC
  1036. #pragma warning(push)
  1037. #pragma warning(disable : 6326) // comparison of two constants
  1038. #endif
  1039. using default_ops::eval_bit_test;
  1040. using default_ops::eval_get_sign;
  1041. using default_ops::eval_increment;
  1042. using default_ops::eval_qr;
  1043. using default_ops::eval_subtract;
  1044. //
  1045. // Special cases first:
  1046. //
  1047. switch (u.exponent())
  1048. {
  1049. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
  1050. {
  1051. switch (v.exponent())
  1052. {
  1053. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
  1054. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
  1055. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  1056. return;
  1057. }
  1058. bool s = u.sign() != v.sign();
  1059. res = u;
  1060. res.sign() = s;
  1061. return;
  1062. }
  1063. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
  1064. {
  1065. switch (v.exponent())
  1066. {
  1067. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity:
  1068. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
  1069. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  1070. return;
  1071. }
  1072. bool s = u.sign() != v.sign();
  1073. res = u;
  1074. res.sign() = s;
  1075. return;
  1076. }
  1077. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
  1078. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  1079. return;
  1080. }
  1081. switch (v.exponent())
  1082. {
  1083. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
  1084. {
  1085. bool s = u.sign() != v.sign();
  1086. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
  1087. res.sign() = s;
  1088. return;
  1089. }
  1090. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity:
  1091. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  1092. res.bits() = limb_type(0);
  1093. res.sign() = u.sign() != v.sign();
  1094. return;
  1095. case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
  1096. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  1097. return;
  1098. }
  1099. // We can scale u and v so that both are integers, then perform integer
  1100. // division to obtain quotient q and remainder r, such that:
  1101. //
  1102. // q * v + r = u
  1103. //
  1104. // and hense:
  1105. //
  1106. // q + r/v = u/v
  1107. //
  1108. // From this, assuming q has cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count
  1109. // bits we only need to determine whether
  1110. // r/v is less than, equal to, or greater than 0.5 to determine rounding -
  1111. // this we can do with a shift and comparison.
  1112. //
  1113. // We can set the exponent and sign of the result up front:
  1114. //
  1115. if ((v.exponent() < 0) && (u.exponent() > 0))
  1116. {
  1117. // Check for overflow:
  1118. if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + v.exponent() < u.exponent() - 1)
  1119. {
  1120. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
  1121. res.sign() = u.sign() != v.sign();
  1122. res.bits() = static_cast<limb_type>(0u);
  1123. return;
  1124. }
  1125. }
  1126. else if ((v.exponent() > 0) && (u.exponent() < 0))
  1127. {
  1128. // Check for underflow:
  1129. if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent + v.exponent() > u.exponent())
  1130. {
  1131. // We will certainly underflow:
  1132. res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  1133. res.sign() = u.sign() != v.sign();
  1134. res.bits() = static_cast<limb_type>(0u);
  1135. return;
  1136. }
  1137. }
  1138. res.exponent() = u.exponent() - v.exponent() - 1;
  1139. res.sign() = u.sign() != v.sign();
  1140. //
  1141. // Now get the quotient and remainder:
  1142. //
  1143. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), t2(v.bits()), q, r;
  1144. eval_left_shift(t, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count);
  1145. eval_qr(t, t2, q, r);
  1146. //
  1147. // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count"
  1148. // or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant
  1149. // bits in q.
  1150. //
  1151. constexpr unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
  1152. if (eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
  1153. {
  1154. //
  1155. // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 bits,
  1156. // so we already have rounding info,
  1157. // we just need to changes things if the last bit is 1 and either the
  1158. // remainder is non-zero (ie we do not have a tie) or the quotient would
  1159. // be odd if it were shifted to the correct number of bits (ie a tiebreak).
  1160. //
  1161. BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
  1162. if ((q.limbs()[0] & 1u) && (eval_get_sign(r) || (q.limbs()[0] & 2u)))
  1163. {
  1164. eval_increment(q);
  1165. }
  1166. }
  1167. else
  1168. {
  1169. //
  1170. // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" bits in q.
  1171. // Get rounding info, which we can get by comparing 2r with v.
  1172. // We want to call copy_and_round to handle rounding and general cleanup,
  1173. // so we'll left shift q and add some fake digits on the end to represent
  1174. // how we'll be rounding.
  1175. //
  1176. using local_exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
  1177. BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
  1178. constexpr unsigned lshift = (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits) ? 2 : limb_bits;
  1179. eval_left_shift(q, lshift);
  1180. res.exponent() -= static_cast<local_exponent_type>(lshift);
  1181. eval_left_shift(r, 1u);
  1182. int c = r.compare(v.bits());
  1183. if (c == 0)
  1184. q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
  1185. else if (c > 0)
  1186. q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
  1187. }
  1188. copy_and_round(res, q);
  1189. #ifdef BOOST_MSVC
  1190. #pragma warning(pop)
  1191. #endif
  1192. }
  1193. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  1194. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
  1195. inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  1196. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& arg)
  1197. {
  1198. eval_divide(res, res, arg);
  1199. }
  1200. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  1201. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class U>
  1202. inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  1203. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u, const U& v)
  1204. {
  1205. #ifdef BOOST_MSVC
  1206. #pragma warning(push)
  1207. #pragma warning(disable : 6326) // comparison of two constants
  1208. #endif
  1209. using default_ops::eval_bit_test;
  1210. using default_ops::eval_get_sign;
  1211. using default_ops::eval_increment;
  1212. using default_ops::eval_qr;
  1213. using default_ops::eval_subtract;
  1214. //
  1215. // Special cases first:
  1216. //
  1217. switch (u.exponent())
  1218. {
  1219. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
  1220. {
  1221. if (v == 0)
  1222. {
  1223. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  1224. return;
  1225. }
  1226. bool s = u.sign() != (v < 0);
  1227. res = u;
  1228. res.sign() = s;
  1229. return;
  1230. }
  1231. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
  1232. res = u;
  1233. return;
  1234. case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
  1235. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  1236. return;
  1237. }
  1238. if (v == 0)
  1239. {
  1240. bool s = u.sign();
  1241. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
  1242. res.sign() = s;
  1243. return;
  1244. }
  1245. // We can scale u and v so that both are integers, then perform integer
  1246. // division to obtain quotient q and remainder r, such that:
  1247. //
  1248. // q * v + r = u
  1249. //
  1250. // and hense:
  1251. //
  1252. // q + r/v = u/v
  1253. //
  1254. // From this, assuming q has "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, we only need to determine whether
  1255. // r/v is less than, equal to, or greater than 0.5 to determine rounding -
  1256. // this we can do with a shift and comparison.
  1257. //
  1258. // We can set the exponent and sign of the result up front:
  1259. //
  1260. std::ptrdiff_t gb = static_cast<std::ptrdiff_t>(msb(v));
  1261. res.exponent() = u.exponent() - static_cast<Exponent>(gb) - static_cast<Exponent>(1);
  1262. res.sign() = u.sign();
  1263. //
  1264. // Now get the quotient and remainder:
  1265. //
  1266. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), q, r;
  1267. eval_left_shift(t, static_cast<double_limb_type>(gb + 1));
  1268. eval_qr(t, number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v), q, r);
  1269. //
  1270. // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
  1271. //
  1272. constexpr unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
  1273. if (eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
  1274. {
  1275. //
  1276. // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, so we already have rounding info,
  1277. // we just need to changes things if the last bit is 1 and the
  1278. // remainder is non-zero (ie we do not have a tie).
  1279. //
  1280. BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
  1281. if ((q.limbs()[0] & 1u) && eval_get_sign(r))
  1282. {
  1283. eval_increment(q);
  1284. }
  1285. }
  1286. else
  1287. {
  1288. //
  1289. // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
  1290. // Get rounding info, which we can get by comparing 2r with v.
  1291. // We want to call copy_and_round to handle rounding and general cleanup,
  1292. // so we'll left shift q and add some fake cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count on the end to represent
  1293. // how we'll be rounding.
  1294. //
  1295. using local_exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
  1296. BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
  1297. constexpr unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits;
  1298. eval_left_shift(q, lshift);
  1299. res.exponent() -= static_cast<local_exponent_type>(lshift);
  1300. eval_left_shift(r, 1u);
  1301. int c = r.compare(number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v));
  1302. if (c == 0)
  1303. q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
  1304. else if (c > 0)
  1305. q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
  1306. }
  1307. copy_and_round(res, q);
  1308. #ifdef BOOST_MSVC
  1309. #pragma warning(pop)
  1310. #endif
  1311. }
  1312. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
  1313. inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const U& v)
  1314. {
  1315. eval_divide(res, res, v);
  1316. }
  1317. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  1318. class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class S>
  1319. inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
  1320. const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u, const S& v)
  1321. {
  1322. using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type;
  1323. eval_divide(res, u, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(v)));
  1324. if (v < 0)
  1325. res.negate();
  1326. }
  1327. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
  1328. inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const S& v)
  1329. {
  1330. eval_divide(res, res, v);
  1331. }
  1332. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1333. inline int eval_get_sign(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1334. {
  1335. return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero ? 0 : arg.sign() ? -1 : 1;
  1336. }
  1337. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1338. inline bool eval_is_zero(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1339. {
  1340. return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  1341. }
  1342. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1343. inline bool eval_eq(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& a, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& b)
  1344. {
  1345. if (a.exponent() == b.exponent())
  1346. {
  1347. if (a.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero)
  1348. return true;
  1349. return (a.sign() == b.sign()) && (a.bits().compare(b.bits()) == 0) && (a.exponent() != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan);
  1350. }
  1351. return false;
  1352. }
  1353. template <class I, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1354. inline void convert_to_signed_int(I* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1355. {
  1356. static constexpr int digits = std::numeric_limits<I>::is_specialized ? std::numeric_limits<I>::digits : sizeof(I) * CHAR_BIT - 1;
  1357. static constexpr I max_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::max)() : (((I(1) << (sizeof(I) * CHAR_BIT - 2)) - 1) << 1) + 1;
  1358. static constexpr I min_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::min)() : -max_val - 1;
  1359. switch (arg.exponent())
  1360. {
  1361. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1362. *res = 0;
  1363. return;
  1364. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1365. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1366. return;
  1367. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1368. *res = max_val;
  1369. if (arg.sign())
  1370. *res = -*res;
  1371. return;
  1372. }
  1373. using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
  1374. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
  1375. shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
  1376. if (shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
  1377. {
  1378. *res = 0;
  1379. return;
  1380. }
  1381. if (arg.sign() && (arg.compare(min_val) <= 0))
  1382. {
  1383. *res = min_val;
  1384. return;
  1385. }
  1386. else if (!arg.sign() && (arg.compare(max_val) >= 0))
  1387. {
  1388. *res = max_val;
  1389. return;
  1390. }
  1391. if (shift < 0)
  1392. {
  1393. if (static_cast<int>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - static_cast<int>(shift) <= digits)
  1394. {
  1395. // We have more bits in long_long_type than the float, so it's OK to left shift:
  1396. eval_convert_to(res, man);
  1397. *res <<= -shift;
  1398. }
  1399. else
  1400. {
  1401. *res = (std::numeric_limits<I>::max)();
  1402. return;
  1403. }
  1404. }
  1405. else
  1406. {
  1407. eval_right_shift(man, static_cast<double_limb_type>(shift));
  1408. eval_convert_to(res, man);
  1409. }
  1410. if (arg.sign())
  1411. {
  1412. *res = -*res;
  1413. }
  1414. }
  1415. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1416. inline void eval_convert_to(long long* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1417. {
  1418. convert_to_signed_int(res, arg);
  1419. }
  1420. #ifdef BOOST_HAS_INT128
  1421. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1422. inline void eval_convert_to(int128_type* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1423. {
  1424. convert_to_signed_int(res, arg);
  1425. }
  1426. #endif
  1427. template <class I, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1428. inline void convert_to_unsigned_int(I* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1429. {
  1430. static constexpr int digits = std::numeric_limits<I>::is_specialized ? std::numeric_limits<I>::digits : sizeof(I) * CHAR_BIT;
  1431. static constexpr I max_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::max)() : ~static_cast<I>(0);
  1432. switch (arg.exponent())
  1433. {
  1434. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1435. *res = 0;
  1436. return;
  1437. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1438. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
  1439. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1440. *res = max_val;
  1441. return;
  1442. }
  1443. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
  1444. using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
  1445. shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
  1446. if (shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
  1447. {
  1448. *res = 0;
  1449. return;
  1450. }
  1451. else if (shift < 0)
  1452. {
  1453. if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - shift <= digits)
  1454. {
  1455. // We have more bits in ulong_long_type than the float, so it's OK to left shift:
  1456. eval_convert_to(res, man);
  1457. *res <<= -shift;
  1458. return;
  1459. }
  1460. *res = max_val;
  1461. return;
  1462. }
  1463. eval_right_shift(man, shift);
  1464. eval_convert_to(res, man);
  1465. }
  1466. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1467. inline void eval_convert_to(unsigned long long* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1468. {
  1469. convert_to_unsigned_int(res, arg);
  1470. }
  1471. #ifdef BOOST_HAS_INT128
  1472. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1473. inline void eval_convert_to(uint128_type* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1474. {
  1475. convert_to_unsigned_int(res, arg);
  1476. }
  1477. #endif
  1478. template <class Float, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1479. inline typename std::enable_if<std::is_floating_point<Float>::value>::type eval_convert_to(Float* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& original_arg)
  1480. {
  1481. using conv_type = cpp_bin_float<std::numeric_limits<Float>::digits, digit_base_2, void, Exponent, MinE, MaxE>;
  1482. using common_exp_type = typename std::common_type<typename conv_type::exponent_type, int>::type;
  1483. static constexpr int float_digits = boost::multiprecision::detail::is_float128<Float>::value ? 113 : std::numeric_limits<Float>::digits;
  1484. BOOST_MP_FLOAT128_USING using std::ldexp;
  1485. //
  1486. // Special cases first:
  1487. //
  1488. switch (original_arg.exponent())
  1489. {
  1490. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1491. *res = 0;
  1492. if (original_arg.sign())
  1493. *res = -*res;
  1494. return;
  1495. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1496. BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
  1497. {
  1498. *res = static_cast<Float>(std::numeric_limits<double>::quiet_NaN());
  1499. }
  1500. else
  1501. {
  1502. *res = std::numeric_limits<Float>::quiet_NaN();
  1503. }
  1504. return;
  1505. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1506. BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
  1507. {
  1508. *res = static_cast<Float>((std::numeric_limits<double>::infinity)());
  1509. }
  1510. else
  1511. {
  1512. *res = (std::numeric_limits<Float>::infinity)();
  1513. }
  1514. if (original_arg.sign())
  1515. *res = -*res;
  1516. return;
  1517. }
  1518. //
  1519. // Check for super large exponent that must be converted to infinity:
  1520. //
  1521. if (original_arg.exponent() > (boost::multiprecision::detail::is_float128<Float>::value ? 16384 : std::numeric_limits<Float>::max_exponent))
  1522. {
  1523. BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
  1524. {
  1525. *res = static_cast<Float>(std::numeric_limits<double>::infinity());
  1526. }
  1527. else
  1528. {
  1529. *res = std::numeric_limits<Float>::has_infinity ? std::numeric_limits<Float>::infinity() : (std::numeric_limits<Float>::max)();
  1530. }
  1531. if (original_arg.sign())
  1532. *res = -*res;
  1533. return;
  1534. }
  1535. //
  1536. // Figure out how many digits we will have in our result,
  1537. // allowing for a possibly denormalized result:
  1538. //
  1539. common_exp_type digits_to_round_to = float_digits;
  1540. if (original_arg.exponent() < std::numeric_limits<Float>::min_exponent - 1)
  1541. {
  1542. common_exp_type diff = original_arg.exponent();
  1543. diff -= boost::multiprecision::detail::is_float128<Float>::value ? -16382 : std::numeric_limits<Float>::min_exponent - 1;
  1544. digits_to_round_to += diff;
  1545. }
  1546. if (digits_to_round_to < 0)
  1547. {
  1548. // Result must be zero:
  1549. *res = 0;
  1550. if (original_arg.sign())
  1551. *res = -*res;
  1552. return;
  1553. }
  1554. //
  1555. // Perform rounding first, then afterwards extract the digits:
  1556. //
  1557. cpp_bin_float<static_cast<unsigned>(float_digits), digit_base_2, Allocator, Exponent, MinE, MaxE> arg;
  1558. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type bits(original_arg.bits());
  1559. arg.exponent() = original_arg.exponent();
  1560. copy_and_round(arg, bits, (std::ptrdiff_t)digits_to_round_to);
  1561. common_exp_type e = arg.exponent();
  1562. e -= static_cast<common_exp_type>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1;
  1563. constexpr std::size_t limbs_needed = static_cast<std::size_t>(float_digits) / (sizeof(*arg.bits().limbs()) * CHAR_BIT) + (static_cast<std::size_t>(float_digits) % (sizeof(*arg.bits().limbs()) * CHAR_BIT) ? 1 : 0);
  1564. std::size_t first_limb_needed = arg.bits().size() - limbs_needed;
  1565. *res = 0;
  1566. e += static_cast<common_exp_type>(first_limb_needed * sizeof(*arg.bits().limbs()) * CHAR_BIT);
  1567. while (first_limb_needed < arg.bits().size())
  1568. {
  1569. *res += ldexp(static_cast<Float>(arg.bits().limbs()[first_limb_needed]), static_cast<int>(e));
  1570. ++first_limb_needed;
  1571. e += static_cast<common_exp_type>(sizeof(*arg.bits().limbs()) * CHAR_BIT);
  1572. }
  1573. if (original_arg.sign())
  1574. *res = -*res;
  1575. }
  1576. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1577. inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, Exponent* e)
  1578. {
  1579. switch (arg.exponent())
  1580. {
  1581. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1582. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1583. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1584. *e = 0;
  1585. res = arg;
  1586. return;
  1587. }
  1588. res = arg;
  1589. *e = arg.exponent() + 1;
  1590. res.exponent() = -1;
  1591. }
  1592. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
  1593. inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I* pe)
  1594. {
  1595. Exponent e;
  1596. eval_frexp(res, arg, &e);
  1597. if ((e > (std::numeric_limits<I>::max)()) || (e < (std::numeric_limits<I>::min)()))
  1598. {
  1599. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Exponent was outside of the range of the argument type to frexp."));
  1600. }
  1601. *pe = static_cast<I>(e);
  1602. }
  1603. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1604. inline void eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, Exponent e)
  1605. {
  1606. switch (arg.exponent())
  1607. {
  1608. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1609. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1610. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1611. res = arg;
  1612. return;
  1613. }
  1614. if ((e > 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent - e < arg.exponent()))
  1615. {
  1616. // Overflow:
  1617. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
  1618. res.sign() = arg.sign();
  1619. }
  1620. else if ((e < 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - e > arg.exponent()))
  1621. {
  1622. // Underflow:
  1623. res = limb_type(0);
  1624. }
  1625. else
  1626. {
  1627. res = arg;
  1628. res.exponent() += e;
  1629. }
  1630. }
  1631. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
  1632. inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I e)
  1633. {
  1634. using si_type = typename boost::multiprecision::detail::make_signed<I>::type;
  1635. if (e > static_cast<I>((std::numeric_limits<si_type>::max)()))
  1636. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
  1637. else
  1638. eval_ldexp(res, arg, static_cast<si_type>(e));
  1639. }
  1640. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
  1641. inline typename std::enable_if<boost::multiprecision::detail::is_signed<I>::value && boost::multiprecision::detail::is_integral<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I e)
  1642. {
  1643. if ((e > (std::numeric_limits<Exponent>::max)()) || (e < (std::numeric_limits<Exponent>::min)()))
  1644. {
  1645. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
  1646. if (e < 0)
  1647. res.negate();
  1648. }
  1649. else
  1650. eval_ldexp(res, arg, static_cast<Exponent>(e));
  1651. }
  1652. /*
  1653. * Sign manipulation
  1654. */
  1655. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  1656. unsigned Digits2, digit_base_type DigitBase2, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
  1657. inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits2, DigitBase2, Allocator2, Exponent2, MinE2, MaxE2>& arg)
  1658. {
  1659. res = arg;
  1660. res.sign() = false;
  1661. }
  1662. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1663. inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1664. {
  1665. res = arg;
  1666. res.sign() = false;
  1667. }
  1668. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
  1669. unsigned Digits2, digit_base_type DigitBase2, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
  1670. inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits2, DigitBase2, Allocator2, Exponent2, MinE2, MaxE2>& arg)
  1671. {
  1672. res = arg;
  1673. res.sign() = false;
  1674. }
  1675. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1676. inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1677. {
  1678. res = arg;
  1679. res.sign() = false;
  1680. }
  1681. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1682. inline int eval_fpclassify(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1683. {
  1684. switch (arg.exponent())
  1685. {
  1686. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1687. return FP_ZERO;
  1688. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1689. return FP_INFINITE;
  1690. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1691. return FP_NAN;
  1692. }
  1693. return FP_NORMAL;
  1694. }
  1695. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1696. inline void eval_sqrt(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1697. {
  1698. using default_ops::eval_bit_test;
  1699. using default_ops::eval_increment;
  1700. using default_ops::eval_integer_sqrt;
  1701. switch (arg.exponent())
  1702. {
  1703. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1704. errno = EDOM;
  1705. // fallthrough...
  1706. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1707. res = arg;
  1708. return;
  1709. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1710. if (arg.sign())
  1711. {
  1712. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  1713. errno = EDOM;
  1714. }
  1715. else
  1716. res = arg;
  1717. return;
  1718. }
  1719. if (arg.sign())
  1720. {
  1721. res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  1722. errno = EDOM;
  1723. return;
  1724. }
  1725. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(arg.bits()), r, s;
  1726. eval_left_shift(t, arg.exponent() & 1 ? cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count : cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1);
  1727. eval_integer_sqrt(s, r, t);
  1728. if (!eval_bit_test(s, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
  1729. {
  1730. // We have exactly the right number of cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in the result, round as required:
  1731. if (s.compare(r) < 0)
  1732. {
  1733. eval_increment(s);
  1734. }
  1735. }
  1736. typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type ae = arg.exponent();
  1737. res.exponent() = ae / 2;
  1738. res.sign() = false;
  1739. if ((ae & 1) && (ae < 0))
  1740. --res.exponent();
  1741. copy_and_round(res, s);
  1742. }
  1743. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1744. inline void eval_floor(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1745. {
  1746. using default_ops::eval_increment;
  1747. switch (arg.exponent())
  1748. {
  1749. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1750. errno = EDOM;
  1751. // fallthrough...
  1752. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1753. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1754. res = arg;
  1755. return;
  1756. }
  1757. using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
  1758. shift_type shift =
  1759. (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
  1760. if ((arg.exponent() > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
  1761. {
  1762. // Either arg is already an integer, or a special value:
  1763. res = arg;
  1764. return;
  1765. }
  1766. if (shift >= (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
  1767. {
  1768. res = static_cast<signed_limb_type>(arg.sign() ? -1 : 0);
  1769. return;
  1770. }
  1771. bool fractional = (shift_type)eval_lsb(arg.bits()) < shift;
  1772. res = arg;
  1773. eval_right_shift(res.bits(), static_cast<double_limb_type>(shift));
  1774. if (fractional && res.sign())
  1775. {
  1776. eval_increment(res.bits());
  1777. const std::ptrdiff_t shift_check =
  1778. static_cast<std::ptrdiff_t>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1 - static_cast<std::ptrdiff_t>(shift));
  1779. if (static_cast<std::ptrdiff_t>(eval_msb(res.bits())) != shift_check)
  1780. {
  1781. // Must have extended result by one bit in the increment:
  1782. --shift;
  1783. ++res.exponent();
  1784. }
  1785. }
  1786. eval_left_shift(res.bits(), static_cast<double_limb_type>(shift));
  1787. }
  1788. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  1789. inline void eval_ceil(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
  1790. {
  1791. using default_ops::eval_increment;
  1792. switch (arg.exponent())
  1793. {
  1794. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
  1795. errno = EDOM;
  1796. // fallthrough...
  1797. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
  1798. case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
  1799. res = arg;
  1800. return;
  1801. }
  1802. using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
  1803. shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
  1804. if ((arg.exponent() > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
  1805. {
  1806. // Either arg is already an integer, or a special value:
  1807. res = arg;
  1808. return;
  1809. }
  1810. if (shift >= (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
  1811. {
  1812. bool s = arg.sign(); // takes care of signed zeros
  1813. res = static_cast<signed_limb_type>(arg.sign() ? 0 : 1);
  1814. res.sign() = s;
  1815. return;
  1816. }
  1817. bool fractional = (shift_type)eval_lsb(arg.bits()) < shift;
  1818. res = arg;
  1819. eval_right_shift(res.bits(), shift);
  1820. if (fractional && !res.sign())
  1821. {
  1822. eval_increment(res.bits());
  1823. if ((std::ptrdiff_t)eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift)
  1824. {
  1825. // Must have extended result by one bit in the increment:
  1826. --shift;
  1827. ++res.exponent();
  1828. }
  1829. }
  1830. eval_left_shift(res.bits(), shift);
  1831. }
  1832. template <unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2>
  1833. int eval_signbit(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val)
  1834. {
  1835. return val.sign();
  1836. }
  1837. template <unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2>
  1838. inline std::size_t hash_value(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val)
  1839. {
  1840. std::size_t result = hash_value(val.bits());
  1841. boost::multiprecision::detail::hash_combine(result, val.exponent(), val.sign());
  1842. return result;
  1843. }
  1844. } // namespace backends
  1845. namespace detail {
  1846. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
  1847. struct transcendental_reduction_type<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> >
  1848. {
  1849. //
  1850. // The type used for trigonometric reduction needs 3 times the precision of the base type.
  1851. // This is double the precision of the original type, plus the largest exponent supported.
  1852. // As a practical measure the largest argument supported is 1/eps, as supporting larger
  1853. // arguments requires the division of argument by PI/2 to also be done at higher precision,
  1854. // otherwise the result (an integer) can not be represented exactly.
  1855. //
  1856. // See ARGUMENT REDUCTION FOR HUGE ARGUMENTS. K C Ng.
  1857. //
  1858. using type = boost::multiprecision::backends::cpp_bin_float<
  1859. boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent>::bit_count * 3,
  1860. boost::multiprecision::backends::digit_base_2,
  1861. Allocator, Exponent, MinExponent, MaxExponent>;
  1862. };
  1863. #ifdef BOOST_HAS_INT128
  1864. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
  1865. struct is_convertible_arithmetic<int128_type, boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> > : public std::true_type
  1866. {};
  1867. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
  1868. struct is_convertible_arithmetic<uint128_type, boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> > : public std::true_type
  1869. {};
  1870. #endif
  1871. } // namespace detail
  1872. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
  1873. inline boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>
  1874. copysign BOOST_PREVENT_MACRO_SUBSTITUTION(
  1875. const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& a,
  1876. const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& b)
  1877. {
  1878. boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> res(a);
  1879. res.backend().sign() = b.backend().sign();
  1880. return res;
  1881. }
  1882. template <unsigned Digits, backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator>
  1883. struct number_category<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > : public std::integral_constant<int, boost::multiprecision::number_kind_floating_point>
  1884. {};
  1885. template <unsigned Digits, backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
  1886. struct is_equivalent_number_type<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2> >
  1887. : public std::integral_constant<bool, true> {};
  1888. } // namespace multiprecision
  1889. namespace math {
  1890. using boost::multiprecision::copysign;
  1891. using boost::multiprecision::signbit;
  1892. } // namespace math
  1893. } // namespace boost
  1894. #include <boost/multiprecision/cpp_bin_float/io.hpp>
  1895. #include <boost/multiprecision/cpp_bin_float/transcendental.hpp>
  1896. namespace std {
  1897. //
  1898. // numeric_limits [partial] specializations for the types declared in this header:
  1899. //
  1900. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  1901. class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >
  1902. {
  1903. using number_type = boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>;
  1904. private:
  1905. //
  1906. // Functions to calculate cached values stored in static values:
  1907. //
  1908. static number_type get_min()
  1909. {
  1910. using ui_type = typename std::tuple_element<0, typename number_type::backend_type::unsigned_types>::type;
  1911. number_type value(ui_type(1u));
  1912. value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
  1913. return value;
  1914. }
  1915. #ifdef BOOST_MSVC
  1916. #pragma warning(push)
  1917. #pragma warning(disable : 4127) // conditional expression is constant
  1918. #endif
  1919. static number_type get_max()
  1920. {
  1921. number_type value;
  1922. BOOST_IF_CONSTEXPR(std::is_void<Allocator>::value)
  1923. eval_complement(value.backend().bits(), value.backend().bits());
  1924. else
  1925. {
  1926. // We jump through hoops here using the backend type directly just to keep VC12 happy
  1927. // (ie compiler workaround, for very strange compiler bug):
  1928. using boost::multiprecision::default_ops::eval_add;
  1929. using boost::multiprecision::default_ops::eval_decrement;
  1930. using boost::multiprecision::default_ops::eval_left_shift;
  1931. using int_backend_type = typename number_type::backend_type::rep_type;
  1932. using ui_type = typename std::tuple_element<0, typename int_backend_type::unsigned_types>::type;
  1933. int_backend_type i;
  1934. i = ui_type(1u);
  1935. eval_left_shift(i, boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1);
  1936. int_backend_type j(i);
  1937. eval_decrement(i);
  1938. eval_add(j, i);
  1939. value.backend().bits() = j;
  1940. }
  1941. value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
  1942. return value;
  1943. }
  1944. #ifdef BOOST_MSVC
  1945. #pragma warning(pop)
  1946. #endif
  1947. static number_type get_epsilon()
  1948. {
  1949. using ui_type = typename std::tuple_element<0, typename number_type::backend_type::unsigned_types>::type;
  1950. number_type value(ui_type(1u));
  1951. return ldexp(value, 1 - static_cast<int>(digits));
  1952. }
  1953. // What value should this be????
  1954. static number_type get_round_error()
  1955. {
  1956. // returns 0.5
  1957. return ldexp(number_type(1u), -1);
  1958. }
  1959. static number_type get_infinity()
  1960. {
  1961. number_type value;
  1962. value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
  1963. return value;
  1964. }
  1965. static number_type get_quiet_NaN()
  1966. {
  1967. number_type value;
  1968. value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan;
  1969. return value;
  1970. }
  1971. public:
  1972. static constexpr bool is_specialized = true;
  1973. static number_type(min)()
  1974. {
  1975. // C++11 thread safe static initialization:
  1976. static number_type value = get_min();
  1977. return value;
  1978. }
  1979. static number_type(max)()
  1980. {
  1981. // C++11 thread safe static initialization:
  1982. static number_type value = get_max();
  1983. return value;
  1984. }
  1985. static constexpr number_type lowest()
  1986. {
  1987. return -(max)();
  1988. }
  1989. static constexpr int digits = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count;
  1990. static constexpr int digits10 = boost::multiprecision::detail::calc_digits10<static_cast<unsigned>(digits)>::value;
  1991. // Is this really correct???
  1992. static constexpr int max_digits10 = boost::multiprecision::detail::calc_max_digits10<static_cast<unsigned>(digits)>::value;
  1993. static constexpr bool is_signed = true;
  1994. static constexpr bool is_integer = false;
  1995. static constexpr bool is_exact = false;
  1996. static constexpr int radix = 2;
  1997. static number_type epsilon()
  1998. {
  1999. // C++11 thread safe static initialization:
  2000. static number_type value = get_epsilon();
  2001. return value;
  2002. }
  2003. // What value should this be????
  2004. static number_type round_error()
  2005. {
  2006. // returns 0.5
  2007. // C++11 thread safe static initialization:
  2008. static number_type value = get_round_error();
  2009. return value;
  2010. }
  2011. static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
  2012. static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent10 = (min_exponent / 1000) * 301L;
  2013. static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
  2014. static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent10 = (max_exponent / 1000) * 301L;
  2015. static constexpr bool has_infinity = true;
  2016. static constexpr bool has_quiet_NaN = true;
  2017. static constexpr bool has_signaling_NaN = false;
  2018. static constexpr float_denorm_style has_denorm = denorm_absent;
  2019. static constexpr bool has_denorm_loss = false;
  2020. static number_type infinity()
  2021. {
  2022. // C++11 thread safe static initialization:
  2023. static number_type value = get_infinity();
  2024. return value;
  2025. }
  2026. static number_type quiet_NaN()
  2027. {
  2028. // C++11 thread safe static initialization:
  2029. static number_type value = get_quiet_NaN();
  2030. return value;
  2031. }
  2032. static constexpr number_type signaling_NaN()
  2033. {
  2034. return number_type(0);
  2035. }
  2036. static constexpr number_type denorm_min() { return get_min(); }
  2037. static constexpr bool is_iec559 = false;
  2038. static constexpr bool is_bounded = true;
  2039. static constexpr bool is_modulo = false;
  2040. static constexpr bool traps = true;
  2041. static constexpr bool tinyness_before = false;
  2042. static constexpr float_round_style round_style = round_to_nearest;
  2043. };
  2044. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2045. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits;
  2046. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2047. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits10;
  2048. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2049. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_digits10;
  2050. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2051. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_signed;
  2052. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2053. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_integer;
  2054. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2055. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_exact;
  2056. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2057. constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::radix;
  2058. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2059. constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent;
  2060. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2061. constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent10;
  2062. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2063. constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent;
  2064. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2065. constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent10;
  2066. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2067. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_infinity;
  2068. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2069. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_quiet_NaN;
  2070. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2071. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_signaling_NaN;
  2072. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2073. constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm;
  2074. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2075. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm_loss;
  2076. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2077. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_iec559;
  2078. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2079. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_bounded;
  2080. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2081. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_modulo;
  2082. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2083. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::traps;
  2084. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2085. constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::tinyness_before;
  2086. template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
  2087. constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::round_style;
  2088. } // namespace std
  2089. #endif