File indexing completed on 2025-04-19 08:19:37
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_CHARCONV_DETAIL_FASTFLOAT_DECIMAL_TO_BINARY_HPP
0009 #define BOOST_CHARCONV_DETAIL_FASTFLOAT_DECIMAL_TO_BINARY_HPP
0010
0011 #include <boost/charconv/detail/fast_float/float_common.hpp>
0012 #include <boost/charconv/detail/fast_float/fast_table.hpp>
0013 #include <cfloat>
0014 #include <cinttypes>
0015 #include <cmath>
0016 #include <cstdint>
0017 #include <cstdlib>
0018 #include <cstring>
0019
0020 namespace boost { namespace charconv { namespace detail { namespace fast_float {
0021
0022
0023
0024
0025
0026 template <int bit_precision>
0027 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0028 value128 compute_product_approximation(int64_t q, uint64_t w) {
0029 const int index = 2 * int(q - powers::smallest_power_of_five);
0030
0031
0032
0033 value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]);
0034 static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]");
0035 constexpr uint64_t precision_mask = (bit_precision < 64) ?
0036 (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
0037 : uint64_t(0xFFFFFFFFFFFFFFFF);
0038 if((firstproduct.high & precision_mask) == precision_mask) {
0039
0040 value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]);
0041 firstproduct.low += secondproduct.high;
0042 if(secondproduct.high > firstproduct.low) {
0043 firstproduct.high++;
0044 }
0045 }
0046 return firstproduct;
0047 }
0048
0049 namespace detail {
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 constexpr BOOST_FORCEINLINE int32_t power(int32_t q) noexcept {
0066 return (((152170 + 65536) * q) >> 16) + 63;
0067 }
0068 }
0069
0070
0071
0072 template <typename binary>
0073 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14
0074 adjusted_mantissa compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept {
0075 int hilz = int(w >> 63) ^ 1;
0076 adjusted_mantissa answer;
0077 answer.mantissa = w << hilz;
0078 int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent();
0079 answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + invalid_am_bias);
0080 return answer;
0081 }
0082
0083
0084
0085 template <typename binary>
0086 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0087 adjusted_mantissa compute_error(int64_t q, uint64_t w) noexcept {
0088 int lz = leading_zeroes(w);
0089 w <<= lz;
0090 value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
0091 return compute_error_scaled<binary>(q, product.high, lz);
0092 }
0093
0094
0095
0096
0097
0098
0099 template <typename binary>
0100 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0101 adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
0102 adjusted_mantissa answer;
0103 if ((w == 0) || (q < binary::smallest_power_of_ten())) {
0104 answer.power2 = 0;
0105 answer.mantissa = 0;
0106
0107 return answer;
0108 }
0109 if (q > binary::largest_power_of_ten()) {
0110
0111 answer.power2 = binary::infinite_power();
0112 answer.mantissa = 0;
0113 return answer;
0114 }
0115
0116
0117
0118 int lz = leading_zeroes(w);
0119 w <<= lz;
0120
0121
0122
0123
0124
0125
0126 value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 int upperbit = int(product.high >> 63);
0137
0138 answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
0139
0140 answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz - binary::minimum_exponent());
0141 if (answer.power2 <= 0) {
0142
0143 if(-answer.power2 + 1 >= 64) {
0144 answer.power2 = 0;
0145 answer.mantissa = 0;
0146
0147 return answer;
0148 }
0149
0150 answer.mantissa >>= -answer.power2 + 1;
0151
0152
0153 answer.mantissa += (answer.mantissa & 1);
0154 answer.mantissa >>= 1;
0155
0156
0157
0158
0159
0160
0161
0162 answer.power2 = (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) ? 0 : 1;
0163 return answer;
0164 }
0165
0166
0167
0168
0169 if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && (q <= binary::max_exponent_round_to_even()) &&
0170 ((answer.mantissa & 3) == 1) ) {
0171
0172
0173
0174 if((answer.mantissa << (upperbit + 64 - binary::mantissa_explicit_bits() - 3)) == product.high) {
0175 answer.mantissa &= ~uint64_t(1);
0176 }
0177 }
0178
0179 answer.mantissa += (answer.mantissa & 1);
0180 answer.mantissa >>= 1;
0181 if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) {
0182 answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits());
0183 answer.power2++;
0184 }
0185
0186 answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits());
0187 if (answer.power2 >= binary::infinite_power()) {
0188 answer.power2 = binary::infinite_power();
0189 answer.mantissa = 0;
0190 }
0191 return answer;
0192 }
0193
0194 }}}}
0195
0196 #endif