cpp_bin_float.hpp 100 KB

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