Guide
Large numbers in JSON and precision loss
Prevent identifiers and integers above 53 bits from changing while JSON is parsed, formatted, or converted in JavaScript.
by Tools in a Tab · Published on · Reviewed on
Short answer
JSON’s grammar permits integers with many digits, but the program reading them
may not represent every value exactly. JavaScript Number uses binary
floating-point and preserves every integer only through 9007199254740991
(2^53 - 1).
Loss example
{
"id": 9007199254740993
}
A parser that immediately converts the token to Number can round it to
9007199254740992. The JSON syntax is valid; the loss occurs in the consumer’s
numeric representation.
RFC 8259 notes that
integers in [-(2^53)+1, (2^53)-1] are the range where common implementations
can agree on the exact value.
When a string is better
If the digits are an identifier, phone number, account, or code rather than a quantity, a string avoids rounding and retains leading zeros:
{
"id": "9007199254740993"
}
For quantities that require exact arithmetic, agree on a decimal or big-integer
type at both ends and define its serialization. JavaScript BigInt is not
automatically serialized as a JSON number by JSON.stringify.
Token-preserving tools
The Tools in a Tab JSON formatter preserves numeric lexemes while formatting or minifying instead of rounding them through an ordinary parse. JSON to YAML also keeps the digits, but the final consumer must still support them.
Checklist
- Decide whether the field is a quantity or an identifier.
- Test
9007199254740991,9007199254740992, and9007199254740993. - Check parsing, transformation, database storage, and reserialization.
- Avoid exponent notation where the consumer requires exact digits.
- Document the accepted range in the API contract.