This commit is contained in:
Daniel Lemire 2020-11-20 17:05:06 -05:00
parent 8fde4bad4e
commit 7bf5db7216
2 changed files with 26 additions and 5 deletions

View File

@ -63,7 +63,6 @@ namespace {
} // namespace } // namespace
// w * 10 ** q // w * 10 ** q
// The returned value should be a valid ieee64 number that simply need to be packed. // 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 // However, in some very rare cases, the computation will fail. In such cases, we
@ -73,13 +72,13 @@ template <typename binary>
fastfloat_really_inline fastfloat_really_inline
adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept { adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
adjusted_mantissa answer; adjusted_mantissa answer;
if ((w == 0) || (q < smallest_power_of_five)) { if ((w == 0) || (q < binary::smallest_power_of_ten())) {
answer.power2 = 0; answer.power2 = 0;
answer.mantissa = 0; answer.mantissa = 0;
// result should be zero // result should be zero
return answer; return answer;
} }
if (q > largest_power_of_five) { if (q > binary::largest_power_of_ten()) {
// we want to get infinity: // we want to get infinity:
answer.power2 = binary::infinite_power(); answer.power2 = binary::infinite_power();
answer.mantissa = 0; 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 // 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. // 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) { if(!inside_safe_exponent) {
answer.power2 = -1; // This (a negative value) indicates an error condition. answer.power2 = -1; // This (a negative value) indicates an error condition.
return answer; return answer;

View File

@ -233,6 +233,8 @@ template <typename T> struct binary_format {
static constexpr int max_exponent_round_to_even(); static constexpr int max_exponent_round_to_even();
static constexpr int min_exponent_round_to_even(); static constexpr int min_exponent_round_to_even();
static constexpr uint64_t max_mantissa_fast_path(); 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); static constexpr T exact_power_of_ten(int64_t power);
}; };
@ -315,6 +317,25 @@ constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
return powers_of_ten_float[power]; return powers_of_ten_float[power];
} }
template <>
constexpr int binary_format<double>::largest_power_of_ten() {
return 308;
}
template <>
constexpr int binary_format<float>::largest_power_of_ten() {
return 38;
}
template <>
constexpr int binary_format<double>::smallest_power_of_ten() {
return -342;
}
template <>
constexpr int binary_format<float>::smallest_power_of_ten() {
return -65;
}
} // namespace fast_float } // namespace fast_float
// for convenience: // for convenience: