Expand description
The numeric core of C’s strtod for C99 hex floats, shared by every
strtod port in the workspace (calc::engine::strtod, the CALC literal
scanner, and epics-ca-rs’s estdlib, the env-knob parser).
Both ports used to build the significand in an f64 (mant = mant * 16.0 + digit) and then scale it with mant * 2.0f64.powi(exp). That composition
is wrong twice over, and the whole subnormal range paid for it:
powiwith a negative exponent evaluates1.0 / 2^-exp, and2^1074is already infinite — so every exponent below about -1023 scaled the significand by1/inf == 0.0x1p-1074came back as an underflow to zero where glibc returns the exact smallest subnormal.- ERANGE was then guessed back from the result: any subnormal was
reported as an ERANGE overflow. glibc raises ERANGE only when the exact
value is tiny AND inexact, so
0x1p-1023— an exactly representable subnormal — leaves errno clear.
HexSignificand keeps the digits as an exact integer m * 2^e2 with a
sticky bit for anything that falls off the bottom, so the conversion to
f64 is a SINGLE correctly-rounded step (ties to even) and knows precisely
whether it was inexact. Every row of the boundary table in this module’s
tests was probed against the compiled glibc strtod on this platform.
Structs§
- HexSignificand
- A C99 hex float’s significand, accumulated exactly.
Enums§
- Parse
Double Error - The
epicsParseDoublefailure codes (epicsStdlib.h).
Functions§
- epics_
parse_ double - C
epicsParseDouble(str, to, NULL)(epicsStdlib.c:149-176): skip leading whitespace, runstrtod, rejectERANGE, skip trailing whitespace, reject anything left over. - epics_
scan_ double - C
epicsScanDouble(epicsStdlib.h:203) —epicsParseDoublewith the status collapsed to a boolean.