dec2flt
nimony/lib/std/private/dec2flt.nim
Correctly rounded decimal → IEEE-754 binary32/binary64 conversion.
A port of Rust's core::num::dec2flt (library/core/src/num/imp/dec2flt), which implements Daniel Lemire, "Number Parsing at a Gigabyte per Second" (<https://arxiv.org/abs/2101.11408>). It needs no libc: no strtod, no floating-point environment, nothing but 64-bit integer arithmetic and, on the fast path, one correctly rounded float multiply or divide.
The text is read once into a Number, mantissa * 10^exponent with the first 19 significant digits, and then three ever more expensive methods try to turn it into a float:
1. Clinger's fast path: mantissa and power of ten are both exact floats, so a single IEEE multiply/divide rounds exactly once. 2. Eisel–Lemire: multiply the normalized mantissa by a 128-bit truncated power of five and read the result off the top bits. It reports failure (a negative biased exponent) when the truncation might change the rounding; with more than 19 digits it also fails unless mantissa and mantissa + 1 round the same way. 3. Simple Decimal Conversion (Nigel Tao, also Go's strconv): hold up to 768 decimal digits exactly, shift by powers of two until the binary point is in place, and round once.
Unlike Rust's parser, which only accepts a whole string, these are prefix readers in the parseutils style: they return how many characters form the number (0 if none).
func parseFloat64(s: openArray[char]; number: var float64): int64Reads a decimal float at the start of
sintonumber, correctly rounded to nearest, ties to even. Returns the number of characters read, or 0 (leavingnumberalone) ifsdoes not start with a float.func parseFloat32(s: openArray[char]; number: var float32): int64Like
parseFloat64, rounding once, directly to binary32 — never via a float64, which would round twice.