diff --git a/include/fast_float/decimal_to_binary.h b/include/fast_float/decimal_to_binary.h index cdeb44a..e85f550 100644 --- a/include/fast_float/decimal_to_binary.h +++ b/include/fast_float/decimal_to_binary.h @@ -63,7 +63,6 @@ namespace { } // namespace - // w * 10 ** q // The returned value should be a valid ieee64 number that simply need to be packed. // However, in some very rare cases, the computation will fail. In such cases, we @@ -73,13 +72,13 @@ template fastfloat_really_inline adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept { adjusted_mantissa answer; - if ((w == 0) || (q < smallest_power_of_five)) { + if ((w == 0) || (q < binary::smallest_power_of_ten())) { answer.power2 = 0; answer.mantissa = 0; // result should be zero return answer; } - if (q > largest_power_of_five) { + if (q > binary::largest_power_of_ten()) { // we want to get infinity: answer.power2 = binary::infinite_power(); answer.mantissa = 0; @@ -101,7 +100,8 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept { // In some very rare cases, this could happen, in which case we might need a more accurate // computation that what we can provide cheaply. This is very, very unlikely. // - const bool inside_safe_exponent = (q >= 0) && (q <= 55); // always good because 5**q <2**128. + const bool inside_safe_exponent = (q >= -27) && (q <= 55); // always good because 5**q <2**128 when q>=0, + // and otherwise, for q<0, we have 5**-q<2**64 and the 128-bit reciprocal allows for exact computation. if(!inside_safe_exponent) { answer.power2 = -1; // This (a negative value) indicates an error condition. return answer; diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 60e5f6e..299fb5a 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -233,6 +233,8 @@ template struct binary_format { static constexpr int max_exponent_round_to_even(); static constexpr int min_exponent_round_to_even(); static constexpr uint64_t max_mantissa_fast_path(); + static constexpr int largest_power_of_ten(); + static constexpr int smallest_power_of_ten(); static constexpr T exact_power_of_ten(int64_t power); }; @@ -315,6 +317,25 @@ constexpr float binary_format::exact_power_of_ten(int64_t power) { return powers_of_ten_float[power]; } + +template <> +constexpr int binary_format::largest_power_of_ten() { + return 308; +} +template <> +constexpr int binary_format::largest_power_of_ten() { + return 38; +} + +template <> +constexpr int binary_format::smallest_power_of_ten() { + return -342; +} +template <> +constexpr int binary_format::smallest_power_of_ten() { + return -65; +} + } // namespace fast_float // for convenience: @@ -328,4 +349,4 @@ inline std::ostream &operator<<(std::ostream &out, const fast_float::decimal &d) return out; } -#endif +#endif \ No newline at end of file