Skip to main content

Module stdlib

Module stdlib 

Source
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:

  • powi with a negative exponent evaluates 1.0 / 2^-exp, and 2^1074 is already infinite — so every exponent below about -1023 scaled the significand by 1/inf == 0. 0x1p-1074 came 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§

ParseDoubleError
The epicsParseDouble failure codes (epicsStdlib.h).

Functions§

c_isspace
C isspace in the “C” locale: space, \t, \n, \v, \f, \r.
epics_parse_double
C epicsParseDouble(str, to, NULL) — the same function with the remainder refused as S_stdlib_extraneous (epicsStdlib.c:169-170) rather than returned.
epics_parse_double_units
C epicsParseDouble(str, to, units) with a NON-NULL units (epicsStdlib.c:149-176): skip leading whitespace, run strtod, reject ERANGE, skip trailing whitespace, and hand back whatever remains instead of refusing it. This is the form store_double_value uses for filter options (chfPlugin.c:273), which is why {"dbnd":{"d":"0.5 V"}} stores 0.5 rather than failing the parse.
epics_scan_double
C epicsScanDouble (epicsStdlib.h:203) — epicsParseDouble with the status collapsed to a boolean.
epics_str_hash
C epicsStrHash (libcom/src/misc/epicsString.c:365-376 at R7.0.10) — the string hash every general-purpose hash table in base keys on (gpHashLib.c:107, the registry, the record-name directory).