lemire / fast_double_parser

Fast function to parse strings into double (binary64) floating-point values, enforces the RFC 7159 (JSON standard) grammar: 4x faster than strtod
Apache License 2.0
623 stars 58 forks source link

Consider tightening FASTFLOAT_ETC_POWER range #28

Open nigeltao opened 3 years ago

nigeltao commented 3 years ago

include/fast_double_parser.h says:

#define FASTFLOAT_SMALLEST_POWER -325
#define FASTFLOAT_LARGEST_POWER 308

and later, in the compute_float_64 function:

if (unlikely((real_exponent < 1) || (real_exponent > 2046))) {
  *success = false;
  return 0;
}

If you tightened the FASTFLOAT_ETC_POWER range from [-325, +308] to [-307, +288] then you could drop that whole if-check. You'd fail over to the fallback (i.e. strtod) in more cases, but such cases (less than 1e-307 or more than 1e+288, roughly speaking) are arguably rare (e.g. compared to 1e+80 atoms in the universe). On the flip side, you'd have to measure it, but fewer if-checks could lead to faster code for the (still-numerous) common cases.

I picked [-307, +288] because, if power is in that range and i is a non-zero uint64_t then i is roughly in the range [1, 1.85e+19], so (i * (10 ** power)) is in the range [1e-307, 1.85e+307], entirely within [DBL_MIN, DBL_MAX] = [2.23e–308, 1.80e+308].

Tightening the ranges also has the small benefit of shrinking the mantissa_64 and mantissa_128 tables.

lemire commented 3 years ago

Good point worth considering.