decimal_to_binary.hpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright 2020-2023 Daniel Lemire
  2. // Copyright 2023 Matt Borland
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. //
  6. // Derivative of: https://github.com/fastfloat/fast_float
  7. #ifndef BOOST_CHARCONV_DETAIL_FASTFLOAT_DECIMAL_TO_BINARY_HPP
  8. #define BOOST_CHARCONV_DETAIL_FASTFLOAT_DECIMAL_TO_BINARY_HPP
  9. #include <boost/charconv/detail/fast_float/float_common.hpp>
  10. #include <boost/charconv/detail/fast_float/fast_table.hpp>
  11. #include <cfloat>
  12. #include <cinttypes>
  13. #include <cmath>
  14. #include <cstdint>
  15. #include <cstdlib>
  16. #include <cstring>
  17. namespace boost { namespace charconv { namespace detail { namespace fast_float {
  18. // This will compute or rather approximate w * 5**q and return a pair of 64-bit words approximating
  19. // the result, with the "high" part corresponding to the most significant bits and the
  20. // low part corresponding to the least significant bits.
  21. //
  22. template <int bit_precision>
  23. BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
  24. value128 compute_product_approximation(int64_t q, uint64_t w) {
  25. const int index = 2 * int(q - powers::smallest_power_of_five);
  26. // For small values of q, e.g., q in [0,27], the answer is always exact because
  27. // The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
  28. // gives the exact answer.
  29. value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]);
  30. static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]");
  31. constexpr uint64_t precision_mask = (bit_precision < 64) ?
  32. (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
  33. : uint64_t(0xFFFFFFFFFFFFFFFF);
  34. if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower)
  35. // regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed.
  36. value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]);
  37. firstproduct.low += secondproduct.high;
  38. if(secondproduct.high > firstproduct.low) {
  39. firstproduct.high++;
  40. }
  41. }
  42. return firstproduct;
  43. }
  44. namespace detail {
  45. /**
  46. * For q in (0,350), we have that
  47. * f = (((152170 + 65536) * q ) >> 16);
  48. * is equal to
  49. * floor(p) + q
  50. * where
  51. * p = log(5**q)/log(2) = q * log(5)/log(2)
  52. *
  53. * For negative values of q in (-400,0), we have that
  54. * f = (((152170 + 65536) * q ) >> 16);
  55. * is equal to
  56. * -ceil(p) + q
  57. * where
  58. * p = log(5**-q)/log(2) = -q * log(5)/log(2)
  59. */
  60. constexpr BOOST_FORCEINLINE int32_t power(int32_t q) noexcept {
  61. return (((152170 + 65536) * q) >> 16) + 63;
  62. }
  63. } // namespace detail
  64. // create an adjusted mantissa, biased by the invalid power2
  65. // for significant digits already multiplied by 10 ** q.
  66. template <typename binary>
  67. BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14
  68. adjusted_mantissa compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept {
  69. int hilz = int(w >> 63) ^ 1;
  70. adjusted_mantissa answer;
  71. answer.mantissa = w << hilz;
  72. int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent();
  73. answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + invalid_am_bias);
  74. return answer;
  75. }
  76. // w * 10 ** q, without rounding the representation up.
  77. // the power2 in the exponent will be adjusted by invalid_am_bias.
  78. template <typename binary>
  79. BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
  80. adjusted_mantissa compute_error(int64_t q, uint64_t w) noexcept {
  81. int lz = leading_zeroes(w);
  82. w <<= lz;
  83. value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
  84. return compute_error_scaled<binary>(q, product.high, lz);
  85. }
  86. // w * 10 ** q
  87. // The returned value should be a valid ieee64 number that simply need to be packed.
  88. // However, in some very rare cases, the computation will fail. In such cases, we
  89. // return an adjusted_mantissa with a negative power of 2: the caller should recompute
  90. // in such cases.
  91. template <typename binary>
  92. BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
  93. adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
  94. adjusted_mantissa answer;
  95. if ((w == 0) || (q < binary::smallest_power_of_ten())) {
  96. answer.power2 = 0;
  97. answer.mantissa = 0;
  98. // result should be zero
  99. return answer;
  100. }
  101. if (q > binary::largest_power_of_ten()) {
  102. // we want to get infinity:
  103. answer.power2 = binary::infinite_power();
  104. answer.mantissa = 0;
  105. return answer;
  106. }
  107. // At this point in time q is in [powers::smallest_power_of_five, powers::largest_power_of_five].
  108. // We want the most significant bit of i to be 1. Shift if needed.
  109. int lz = leading_zeroes(w);
  110. w <<= lz;
  111. // The required precision is binary::mantissa_explicit_bits() + 3 because
  112. // 1. We need the implicit bit
  113. // 2. We need an extra bit for rounding purposes
  114. // 3. We might lose a bit due to the "upperbit" routine (result too small, requiring a shift)
  115. value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
  116. // The computed 'product' is always sufficient.
  117. // Mathematical proof:
  118. // Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to appear)
  119. // See script/mushtak_lemire.py
  120. // The "compute_product_approximation" function can be slightly slower than a branchless approach:
  121. // value128 product = compute_product(q, w);
  122. // but in practice, we can win big with the compute_product_approximation if its additional branch
  123. // is easily predicted. Which is best is data specific.
  124. int upperbit = int(product.high >> 63);
  125. answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
  126. answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz - binary::minimum_exponent());
  127. if (answer.power2 <= 0) { // we have a subnormal?
  128. // Here have that answer.power2 <= 0 so -answer.power2 >= 0
  129. if(-answer.power2 + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure.
  130. answer.power2 = 0;
  131. answer.mantissa = 0;
  132. // result should be zero
  133. return answer;
  134. }
  135. // next line is safe because -answer.power2 + 1 < 64
  136. answer.mantissa >>= -answer.power2 + 1;
  137. // Thankfully, we can't have both "round-to-even" and subnormals because
  138. // "round-to-even" only occurs for powers close to 0.
  139. answer.mantissa += (answer.mantissa & 1); // round up
  140. answer.mantissa >>= 1;
  141. // There is a weird scenario where we don't have a subnormal but just.
  142. // Suppose we start with 2.2250738585072013e-308, we end up
  143. // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal
  144. // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round
  145. // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer
  146. // subnormal, but we can only know this after rounding.
  147. // So we only declare a subnormal if we are smaller than the threshold.
  148. answer.power2 = (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) ? 0 : 1;
  149. return answer;
  150. }
  151. // usually, we round *up*, but if we fall right in between and and we have an
  152. // even basis, we need to round down
  153. // We are only concerned with the cases where 5**q fits in single 64-bit word.
  154. if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && (q <= binary::max_exponent_round_to_even()) &&
  155. ((answer.mantissa & 3) == 1) ) { // we may fall between two floats!
  156. // To be in-between two floats we need that in doing
  157. // answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
  158. // ... we dropped out only zeroes. But if this happened, then we can go back!!!
  159. if((answer.mantissa << (upperbit + 64 - binary::mantissa_explicit_bits() - 3)) == product.high) {
  160. answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up
  161. }
  162. }
  163. answer.mantissa += (answer.mantissa & 1); // round up
  164. answer.mantissa >>= 1;
  165. if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) {
  166. answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits());
  167. answer.power2++; // undo previous addition
  168. }
  169. answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits());
  170. if (answer.power2 >= binary::infinite_power()) { // infinity
  171. answer.power2 = binary::infinite_power();
  172. answer.mantissa = 0;
  173. }
  174. return answer;
  175. }
  176. }}}} // namespace fast_float
  177. #endif