io.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  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_MP_CPP_BIN_FLOAT_IO_HPP
  6. #define BOOST_MP_CPP_BIN_FLOAT_IO_HPP
  7. #include <boost/multiprecision/detail/no_exceptions_support.hpp>
  8. #include <boost/multiprecision/detail/assert.hpp>
  9. namespace boost { namespace multiprecision {
  10. namespace cpp_bf_io_detail {
  11. //
  12. // Multiplies a by b and shifts the result so it fits inside max_bits bits,
  13. // returns by how much the result was shifted.
  14. //
  15. template <class I>
  16. inline I restricted_multiply(cpp_int& result, const cpp_int& a, const cpp_int& b, I max_bits, std::int64_t& error)
  17. {
  18. using local_integral_type = I;
  19. result = a * b;
  20. local_integral_type gb = static_cast<local_integral_type>(msb(result));
  21. local_integral_type rshift = 0;
  22. if (gb > max_bits)
  23. {
  24. rshift = gb - max_bits;
  25. local_integral_type lb = static_cast<local_integral_type>(lsb(result));
  26. int roundup = 0;
  27. // The error rate increases by the error of both a and b,
  28. // this may be overly pessimistic in many case as we're assuming
  29. // that a and b have the same level of uncertainty...
  30. if (lb < rshift)
  31. error = error ? error * 2 : 1;
  32. if (rshift)
  33. {
  34. BOOST_MP_ASSERT(rshift < INT_MAX);
  35. if (bit_test(result, static_cast<unsigned>(rshift - 1)))
  36. {
  37. if (lb == rshift - 1)
  38. roundup = 1;
  39. else
  40. roundup = 2;
  41. }
  42. result >>= rshift;
  43. }
  44. if ((roundup == 2) || ((roundup == 1) && (result.backend().limbs()[0] & 1)))
  45. ++result;
  46. }
  47. return rshift;
  48. }
  49. //
  50. // Computes a^e shifted to the right so it fits in max_bits, returns how far
  51. // to the right we are shifted.
  52. //
  53. template <class I>
  54. inline I restricted_pow(cpp_int& result, const cpp_int& a, I e, I max_bits, std::int64_t& error)
  55. {
  56. BOOST_MP_ASSERT(&result != &a);
  57. I exp = 0;
  58. if (e == 1)
  59. {
  60. result = a;
  61. return exp;
  62. }
  63. else if (e == 2)
  64. {
  65. return restricted_multiply(result, a, a, max_bits, error);
  66. }
  67. else if (e == 3)
  68. {
  69. exp = restricted_multiply(result, a, a, max_bits, error);
  70. exp += restricted_multiply(result, result, a, max_bits, error);
  71. return exp;
  72. }
  73. I p = e / 2;
  74. exp = restricted_pow(result, a, p, max_bits, error);
  75. exp *= 2;
  76. exp += restricted_multiply(result, result, result, max_bits, error);
  77. if (e & 1)
  78. exp += restricted_multiply(result, result, a, max_bits, error);
  79. return exp;
  80. }
  81. inline int get_round_mode(const cpp_int& what, std::int64_t location, std::int64_t error)
  82. {
  83. //
  84. // Can we round what at /location/, if the error in what is /error/ in
  85. // units of 0.5ulp. Return:
  86. //
  87. // -1: Can't round.
  88. // 0: leave as is.
  89. // 1: tie.
  90. // 2: round up.
  91. //
  92. BOOST_MP_ASSERT(location >= 0);
  93. BOOST_MP_ASSERT(location < INT_MAX);
  94. std::int64_t error_radius = error & 1 ? (1 + error) / 2 : error / 2;
  95. if (error_radius && (static_cast<int>(msb(error_radius)) >= location))
  96. return -1;
  97. if (bit_test(what, static_cast<unsigned>(location)))
  98. {
  99. if (static_cast<int>(lsb(what)) == location)
  100. return error ? -1 : 1; // Either a tie or can't round depending on whether we have any error
  101. if (!error)
  102. return 2; // no error, round up.
  103. cpp_int t = what - error_radius;
  104. if (static_cast<int>(lsb(t)) >= location)
  105. return -1;
  106. return 2;
  107. }
  108. else if (error)
  109. {
  110. cpp_int t = what + error_radius;
  111. return bit_test(t, static_cast<unsigned>(location)) ? -1 : 0;
  112. }
  113. return 0;
  114. }
  115. inline int get_round_mode(cpp_int& r, cpp_int& d, std::int64_t error, const cpp_int& q)
  116. {
  117. //
  118. // Lets suppose we have an inexact division by d+delta, where the true
  119. // value for the divisor is d, and with |delta| <= error/2, then
  120. // we have calculated q and r such that:
  121. //
  122. // n r
  123. // --- = q + -----------
  124. // d + error d + error
  125. //
  126. // Rearranging for n / d we get:
  127. //
  128. // n delta*q + r
  129. // --- = q + -------------
  130. // d d
  131. //
  132. // So rounding depends on whether 2r + error * q > d.
  133. //
  134. // We return:
  135. // 0 = down down.
  136. // 1 = tie.
  137. // 2 = round up.
  138. // -1 = couldn't decide.
  139. //
  140. r <<= 1;
  141. int c = r.compare(d);
  142. if (c == 0)
  143. return error ? -1 : 1;
  144. if (c > 0)
  145. {
  146. if (error)
  147. {
  148. r -= error * q;
  149. return r.compare(d) > 0 ? 2 : -1;
  150. }
  151. return 2;
  152. }
  153. if (error)
  154. {
  155. r += error * q;
  156. return r.compare(d) < 0 ? 0 : -1;
  157. }
  158. return 0;
  159. }
  160. } // namespace cpp_bf_io_detail
  161. namespace backends {
  162. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  163. cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::operator=(const char* s)
  164. {
  165. cpp_int n;
  166. std::intmax_t decimal_exp = 0;
  167. std::intmax_t digits_seen = 0;
  168. constexpr std::intmax_t max_digits_seen = 4 + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count * 301L) / 1000;
  169. bool ss = false;
  170. //
  171. // Extract the sign:
  172. //
  173. if (*s == '-')
  174. {
  175. ss = true;
  176. ++s;
  177. }
  178. else if (*s == '+')
  179. ++s;
  180. //
  181. // Special cases first:
  182. //
  183. if ((std::strcmp(s, "nan") == 0) || (std::strcmp(s, "NaN") == 0) || (std::strcmp(s, "NAN") == 0))
  184. {
  185. return *this = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
  186. }
  187. if ((std::strcmp(s, "inf") == 0) || (std::strcmp(s, "Inf") == 0) || (std::strcmp(s, "INF") == 0) || (std::strcmp(s, "infinity") == 0) || (std::strcmp(s, "Infinity") == 0) || (std::strcmp(s, "INFINITY") == 0))
  188. {
  189. *this = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
  190. if (ss)
  191. negate();
  192. return *this;
  193. }
  194. //
  195. // Digits before the point:
  196. //
  197. while (*s && (*s >= '0') && (*s <= '9'))
  198. {
  199. n *= 10u;
  200. n += *s - '0';
  201. if (digits_seen || (*s != '0'))
  202. ++digits_seen;
  203. ++s;
  204. }
  205. // The decimal point (we really should localise this!!)
  206. if (*s && (*s == '.'))
  207. ++s;
  208. //
  209. // Digits after the point:
  210. //
  211. while (*s && (*s >= '0') && (*s <= '9'))
  212. {
  213. n *= 10u;
  214. n += *s - '0';
  215. --decimal_exp;
  216. if (digits_seen || (*s != '0'))
  217. ++digits_seen;
  218. ++s;
  219. if (digits_seen > max_digits_seen)
  220. break;
  221. }
  222. //
  223. // Digits we're skipping:
  224. //
  225. while (*s && (*s >= '0') && (*s <= '9'))
  226. ++s;
  227. //
  228. // See if there's an exponent:
  229. //
  230. if (*s && ((*s == 'e') || (*s == 'E')))
  231. {
  232. ++s;
  233. std::intmax_t e = 0;
  234. bool es = false;
  235. if (*s && (*s == '-'))
  236. {
  237. es = true;
  238. ++s;
  239. }
  240. else if (*s && (*s == '+'))
  241. ++s;
  242. while (*s && (*s >= '0') && (*s <= '9'))
  243. {
  244. e *= 10u;
  245. e += *s - '0';
  246. ++s;
  247. }
  248. if (es)
  249. e = -e;
  250. decimal_exp += e;
  251. }
  252. if (*s)
  253. {
  254. //
  255. // Oops unexpected input at the end of the number:
  256. //
  257. BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unable to parse string as a valid floating point number."));
  258. }
  259. if (n == 0)
  260. {
  261. // Result is necessarily zero:
  262. *this = static_cast<limb_type>(0u);
  263. return *this;
  264. }
  265. constexpr std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT;
  266. //
  267. // Set our working precision - this is heuristic based, we want
  268. // a value as small as possible > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count to avoid large computations
  269. // and excessive memory usage, but we also want to avoid having to
  270. // up the computation and start again at a higher precision.
  271. // So we round cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count up to the nearest whole number of limbs, and add
  272. // one limb for good measure. This works very well for small exponents,
  273. // but for larger exponents we may may need to restart, we could add some
  274. // extra precision right from the start for larger exponents, but this
  275. // seems to be slightly slower in the *average* case:
  276. //
  277. #ifdef BOOST_MP_STRESS_IO
  278. std::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32;
  279. #else
  280. std::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + ((cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) ? (limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) : 0) + limb_bits;
  281. #endif
  282. std::int64_t error = 0;
  283. std::intmax_t calc_exp = 0;
  284. std::intmax_t final_exponent = 0;
  285. if (decimal_exp >= 0)
  286. {
  287. // Nice and simple, the result is an integer...
  288. do
  289. {
  290. cpp_int t;
  291. if (decimal_exp)
  292. {
  293. calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(t, cpp_int(5), decimal_exp, max_bits, error);
  294. calc_exp += boost::multiprecision::cpp_bf_io_detail::restricted_multiply(t, t, n, max_bits, error);
  295. }
  296. else
  297. t = n;
  298. final_exponent = (std::int64_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 + decimal_exp + calc_exp;
  299. std::ptrdiff_t rshift = static_cast<std::ptrdiff_t>(static_cast<std::ptrdiff_t>(msb(t)) - static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) + 1);
  300. if (rshift > 0)
  301. {
  302. final_exponent += rshift;
  303. int roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(t, rshift - 1, error);
  304. t >>= rshift;
  305. if ((roundup == 2) || ((roundup == 1) && t.backend().limbs()[0] & 1))
  306. ++t;
  307. else if (roundup < 0)
  308. {
  309. #ifdef BOOST_MP_STRESS_IO
  310. max_bits += 32;
  311. #else
  312. max_bits *= 2;
  313. #endif
  314. error = 0;
  315. continue;
  316. }
  317. }
  318. else
  319. {
  320. BOOST_MP_ASSERT(!error);
  321. }
  322. if (final_exponent > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
  323. {
  324. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
  325. final_exponent -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
  326. }
  327. else if (final_exponent < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
  328. {
  329. // Underflow:
  330. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
  331. final_exponent -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
  332. }
  333. else
  334. {
  335. exponent() = static_cast<Exponent>(final_exponent);
  336. final_exponent = 0;
  337. }
  338. copy_and_round(*this, t.backend());
  339. break;
  340. } while (true);
  341. if (ss != sign())
  342. negate();
  343. }
  344. else
  345. {
  346. // Result is the ratio of two integers: we need to organise the
  347. // division so as to produce at least an N-bit result which we can
  348. // round according to the remainder.
  349. //cpp_int d = pow(cpp_int(5), -decimal_exp);
  350. do
  351. {
  352. cpp_int d;
  353. calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(d, cpp_int(5), -decimal_exp, max_bits, error);
  354. const std::ptrdiff_t shift = static_cast<std::ptrdiff_t>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - static_cast<std::ptrdiff_t>(msb(n)) + static_cast<std::ptrdiff_t>(msb(d)));
  355. final_exponent = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 + decimal_exp - calc_exp;
  356. if (shift > 0)
  357. {
  358. n <<= shift;
  359. final_exponent -= static_cast<Exponent>(shift);
  360. }
  361. cpp_int q, r;
  362. divide_qr(n, d, q, r);
  363. std::ptrdiff_t gb = static_cast<std::ptrdiff_t>(msb(q));
  364. BOOST_MP_ASSERT((gb >= static_cast<int>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1));
  365. //
  366. // Check for rounding conditions we have to
  367. // handle ourselves:
  368. //
  369. int roundup = 0;
  370. if (gb == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
  371. {
  372. // Exactly the right number of bits, use the remainder to round:
  373. roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(r, d, error, q);
  374. }
  375. else if (bit_test(q, static_cast<std::size_t>(gb - static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))) && (static_cast<std::ptrdiff_t>(lsb(q)) == static_cast<std::ptrdiff_t>(gb - static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))))
  376. {
  377. // Too many bits in q and the bits in q indicate a tie, but we can break that using r,
  378. // note that the radius of error in r is error/2 * q:
  379. std::ptrdiff_t lshift = gb - static_cast<int>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) + 1;
  380. q >>= lshift;
  381. final_exponent += static_cast<Exponent>(lshift);
  382. BOOST_MP_ASSERT((msb(q) >= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
  383. if (error && (r < (error / 2) * q))
  384. roundup = -1;
  385. else if (error && (r + (error / 2) * q >= d))
  386. roundup = -1;
  387. else
  388. roundup = r ? 2 : 1;
  389. }
  390. else if (error && (((error / 2) * q + r >= d) || (r < (error / 2) * q)))
  391. {
  392. // We might have been rounding up, or got the wrong quotient: can't tell!
  393. roundup = -1;
  394. }
  395. if (roundup < 0)
  396. {
  397. #ifdef BOOST_MP_STRESS_IO
  398. max_bits += 32;
  399. #else
  400. max_bits *= 2;
  401. #endif
  402. error = 0;
  403. if (shift > 0)
  404. {
  405. n >>= shift;
  406. final_exponent += static_cast<Exponent>(shift);
  407. }
  408. continue;
  409. }
  410. else if ((roundup == 2) || ((roundup == 1) && q.backend().limbs()[0] & 1))
  411. ++q;
  412. if (final_exponent > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
  413. {
  414. // Overflow:
  415. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
  416. final_exponent -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
  417. }
  418. else if (final_exponent < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
  419. {
  420. // Underflow:
  421. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
  422. final_exponent -= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
  423. }
  424. else
  425. {
  426. exponent() = static_cast<Exponent>(final_exponent);
  427. final_exponent = 0;
  428. }
  429. copy_and_round(*this, q.backend());
  430. if (ss != sign())
  431. negate();
  432. break;
  433. } while (true);
  434. }
  435. //
  436. // Check for scaling and/or over/under-flow:
  437. //
  438. final_exponent += exponent();
  439. if (final_exponent > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
  440. {
  441. // Overflow:
  442. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
  443. bits() = limb_type(0);
  444. }
  445. else if (final_exponent < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
  446. {
  447. // Underflow:
  448. exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
  449. bits() = limb_type(0);
  450. sign() = 0;
  451. }
  452. else
  453. {
  454. exponent() = static_cast<Exponent>(final_exponent);
  455. }
  456. return *this;
  457. }
  458. template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
  459. std::string cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::str(std::streamsize dig, std::ios_base::fmtflags f) const
  460. {
  461. bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
  462. bool fixed = !scientific && (f & std::ios_base::fixed);
  463. if (dig == 0 && !fixed)
  464. dig = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::max_digits10;
  465. std::string s;
  466. if (exponent() <= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
  467. {
  468. // How far to left-shift in order to demormalise the mantissa:
  469. std::intmax_t shift = (std::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - (std::intmax_t)exponent() - 1;
  470. std::intmax_t digits_wanted = static_cast<int>(dig);
  471. std::intmax_t base10_exp = exponent() >= 0 ? static_cast<std::intmax_t>(std::floor(0.30103 * exponent())) : static_cast<std::intmax_t>(std::ceil(0.30103 * exponent()));
  472. //
  473. // For fixed formatting we want /dig/ digits after the decimal point,
  474. // so if the exponent is zero, allowing for the one digit before the
  475. // decimal point, we want 1 + dig digits etc.
  476. //
  477. if (fixed)
  478. digits_wanted += 1 + base10_exp;
  479. if (scientific)
  480. digits_wanted += 1;
  481. if (digits_wanted < -1)
  482. {
  483. // Fixed precision, no significant digits, and nothing to round!
  484. s = "0";
  485. if (sign())
  486. s.insert(static_cast<std::string::size_type>(0), 1, '-');
  487. boost::multiprecision::detail::format_float_string(s, base10_exp, dig, f, true);
  488. return s;
  489. }
  490. //
  491. // power10 is the base10 exponent we need to multiply/divide by in order
  492. // to convert our denormalised number to an integer with the right number of digits:
  493. //
  494. std::intmax_t power10 = digits_wanted - base10_exp - 1;
  495. //
  496. // If we calculate 5^power10 rather than 10^power10 we need to move
  497. // 2^power10 into /shift/
  498. //
  499. shift -= power10;
  500. cpp_int i;
  501. int roundup = 0; // 0=no rounding, 1=tie, 2=up
  502. constexpr std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT;
  503. //
  504. // Set our working precision - this is heuristic based, we want
  505. // a value as small as possible > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count to avoid large computations
  506. // and excessive memory usage, but we also want to avoid having to
  507. // up the computation and start again at a higher precision.
  508. // So we round cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count up to the nearest whole number of limbs, and add
  509. // one limb for good measure. This works very well for small exponents,
  510. // but for larger exponents we add a few extra limbs to max_bits:
  511. //
  512. #ifdef BOOST_MP_STRESS_IO
  513. std::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32;
  514. #else
  515. std::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + ((cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) ? (limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) : 0) + limb_bits;
  516. if (power10)
  517. {
  518. const std::uintmax_t abs_power10 = static_cast<std::uintmax_t>(boost::multiprecision::detail::abs(power10));
  519. const std::intmax_t msb_div8 = static_cast<std::intmax_t>(msb(abs_power10) / 8u);
  520. max_bits += (msb_div8 * static_cast<std::intmax_t>(limb_bits));
  521. }
  522. #endif
  523. do
  524. {
  525. std::int64_t error = 0;
  526. std::intmax_t calc_exp = 0;
  527. //
  528. // Our integer result is: bits() * 2^-shift * 5^power10
  529. //
  530. i = bits();
  531. if (shift < 0)
  532. {
  533. if (power10 >= 0)
  534. {
  535. // We go straight to the answer with all integer arithmetic,
  536. // the result is always exact and never needs rounding:
  537. BOOST_MP_ASSERT(power10 <= (std::intmax_t)INT_MAX);
  538. i <<= -shift;
  539. if (power10)
  540. i *= pow(cpp_int(5), static_cast<unsigned>(power10));
  541. }
  542. else if (power10 < 0)
  543. {
  544. cpp_int d;
  545. calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(d, cpp_int(5), -power10, max_bits, error);
  546. shift += calc_exp;
  547. BOOST_MP_ASSERT(shift < 0); // Must still be true!
  548. i <<= -shift;
  549. cpp_int r;
  550. divide_qr(i, d, i, r);
  551. roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(r, d, error, i);
  552. if (roundup < 0)
  553. {
  554. #ifdef BOOST_MP_STRESS_IO
  555. max_bits += 32;
  556. #else
  557. max_bits *= 2;
  558. #endif
  559. shift = (std::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10;
  560. continue;
  561. }
  562. }
  563. }
  564. else
  565. {
  566. //
  567. // Our integer is bits() * 2^-shift * 10^power10
  568. //
  569. if (power10 > 0)
  570. {
  571. if (power10)
  572. {
  573. cpp_int t;
  574. calc_exp = boost::multiprecision::cpp_bf_io_detail::restricted_pow(t, cpp_int(5), power10, max_bits, error);
  575. calc_exp += boost::multiprecision::cpp_bf_io_detail::restricted_multiply(i, i, t, max_bits, error);
  576. shift -= calc_exp;
  577. }
  578. if ((shift < 0) || ((shift == 0) && error))
  579. {
  580. // We only get here if we were asked for a crazy number of decimal digits -
  581. // more than are present in a 2^max_bits number.
  582. #ifdef BOOST_MP_STRESS_IO
  583. max_bits += 32;
  584. #else
  585. max_bits *= 2;
  586. #endif
  587. shift = (std::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10;
  588. continue;
  589. }
  590. if (shift)
  591. {
  592. roundup = boost::multiprecision::cpp_bf_io_detail::get_round_mode(i, shift - 1, error);
  593. if (roundup < 0)
  594. {
  595. #ifdef BOOST_MP_STRESS_IO
  596. max_bits += 32;
  597. #else
  598. max_bits *= 2;
  599. #endif
  600. shift = (std::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10;
  601. continue;
  602. }
  603. i >>= shift;
  604. }
  605. }
  606. else
  607. {
  608. // We're right shifting, *and* dividing by 5^-power10,
  609. // so 5^-power10 can never be that large or we'd simply
  610. // get zero as a result, and that case is already handled above:
  611. cpp_int r;
  612. BOOST_MP_ASSERT(-power10 < INT_MAX);
  613. cpp_int d = pow(cpp_int(5), static_cast<unsigned>(-power10));
  614. d <<= shift;
  615. divide_qr(i, d, i, r);
  616. r <<= 1;
  617. int c = r.compare(d);
  618. roundup = c < 0 ? 0 : c == 0 ? 1 : 2;
  619. }
  620. }
  621. s = i.str(0, std::ios_base::fmtflags(0));
  622. //
  623. // Check if we got the right number of digits, this
  624. // is really a test of whether we calculated the
  625. // decimal exponent correctly:
  626. //
  627. std::intmax_t digits_got = i ? static_cast<std::intmax_t>(s.size()) : 0;
  628. if (digits_got != digits_wanted)
  629. {
  630. base10_exp += digits_got - digits_wanted;
  631. if (fixed)
  632. digits_wanted = digits_got; // strange but true.
  633. power10 = digits_wanted - base10_exp - 1;
  634. shift = (std::intmax_t)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - exponent() - 1 - power10;
  635. if (fixed)
  636. break;
  637. roundup = 0;
  638. }
  639. else
  640. break;
  641. } while (true);
  642. //
  643. // Check whether we need to round up: note that we could equally round up
  644. // the integer /i/ above, but since we need to perform the rounding *after*
  645. // the conversion to a string and the digit count check, we might as well
  646. // do it here:
  647. //
  648. if ((roundup == 2) || ((roundup == 1) && ((s[s.size() - 1] - '0') & 1)))
  649. {
  650. boost::multiprecision::detail::round_string_up_at(s, static_cast<int>(s.size() - 1), base10_exp);
  651. }
  652. if (sign())
  653. s.insert(static_cast<std::string::size_type>(0), 1, '-');
  654. boost::multiprecision::detail::format_float_string(s, base10_exp, dig, f, false);
  655. }
  656. else
  657. {
  658. switch (exponent())
  659. {
  660. case exponent_zero:
  661. s = sign() ? "-0" : f & std::ios_base::showpos ? "+0" : "0";
  662. boost::multiprecision::detail::format_float_string(s, 0, dig, f, true);
  663. break;
  664. case exponent_nan:
  665. s = "nan";
  666. break;
  667. case exponent_infinity:
  668. s = sign() ? "-inf" : f & std::ios_base::showpos ? "+inf" : "inf";
  669. break;
  670. }
  671. }
  672. return s;
  673. }
  674. } // namespace backends
  675. }} // namespace boost::multiprecision
  676. #endif