Format floats with a portable round-trip search¶
- Status: accepted
- Date: 2026-09-06
Context and Problem Statement¶
serialize_canonical() must emit a double that reads back as the same value.
An earlier version used fixed-precision std::to_string formatting, which does
not round-trip.
Considered Options¶
- An escalating-precision
snprintf/strtodround-trip search std::to_chars's floating-point overload- Fixed-precision
std::to_string(the earlier behaviour)
Decision Outcome¶
Chosen option: "escalating-precision snprintf/strtod round-trip search",
because std::to_chars's floating-point overload is not implemented on every
supported toolchain — NetBSD's libstdc++ build ships only the integer
overloads. Correctness on Tier 1 BSD platforms outranks using the newer API.
Negative Consequences¶
snprintfandstrtodboth consultLC_NUMERIC. The formatter must normalize the active locale's decimal separator back to., or float output stops being valid JSON the moment any library in the process callssetlocale()(#435). That is a real defect this approach introduced and now guards against;std::to_charswould not have had it.- Slower than a single formatting call, since it may try several precisions.
Positive Consequences¶
- Builds and behaves identically on every supported platform, which is the
property
platform-support.mdexists to protect.
Links¶
docs/canonical-json.md, "Numeric policy"