What even is a JSON number?
JSON numbers vs IEEE-754 and I‑JSON
- Thread centers on how JSON’s “number” maps to IEEE 754 double precision and I‑JSON’s recommendation not to exceed that magnitude/precision.
- Confusion over how to define “precision” of literals like
0.1that cannot be represented exactly. - One interpretation: the message should not imply more precision than a double can store; short forms like
0.1are fine, but very long decimal expansions are misleading.
Language behavior and parser customization
- Many standard JSON libraries default to IEEE‑754 doubles and silently lose digits.
- Several languages offer hooks to avoid this:
- Go
UseNumberto keep numeric strings. - Python
parse_int/parse_floatto map toDecimalorstr. - JavaScript is gaining
JSON.parse“with source” (context) to reconstruct BigInt or custom types, but support is still incomplete across engines.
- Go
- Some recommend using validation/parsing layers (e.g., schema libraries) to coerce JSON numbers into safer internal types.
Integers, IDs, and “safe” ranges
- Multiple anecdotes of 64‑bit identifiers breaking when parsed as JS numbers (precision loss around 2^53).
- Advice: treat IDs as strings in JSON, even if they are integers in databases.
- Counterpoint from data/analytics side: integer keys are significantly faster than strings in large joins, at least inside databases.
Money, decimals, and fixed‑point
- Strong consensus: don’t use JSON binary floats for money.
- Strategies:
- Scale to integers (cents, mills, millicents) and encode as JSON numbers, but this bakes in assumptions about precision and can conflict with varying currency rules and changing standards.
- Store as DECIMAL/BigDecimal in DB and serialize as decimal strings in JSON; let domain logic handle rounding rules.
- Use explicit “money” value objects instead of raw numeric types.
Arbitrary precision, DoS, and limits
- Some libraries (e.g., Haskell’s
Scientific, Rust BigDecimal) parse into arbitrary-precision types. - Concern: untrusted JSON can contain huge exponents or thousands of digits, and naive arithmetic can exhaust memory (potential DoS).
- Proposed mitigations: hard or configurable precision/size limits, separate “huge” vs “normal” numeric types, or failing parsers on oversized numbers.
Spec design, NaN/Inf, and alternatives
- JSON explicitly allows implementations to limit precision; many see this as a fundamental interoperability flaw.
- Lack of NaN/Inf representation forces ad‑hoc handling; some languages serialize them anyway, breaking strict JSON.
- Alternatives mentioned: Mongo Extended JSON, Amazon Ion, XML with schemas; these offer richer, better‑specified numeric types but less ubiquity than plain JSON.