Why JSON Formatting Changes Large Numbers in JavaScript

A formatter that uses JavaScript JSON.parse can round large number literals before displaying them. Preserve exact identifiers as strings at the source. Converting an already rounded Number to a string or BigInt cannot restore missing digits.

Reproduce a changed final digit

This valid JSON has an integer beyond JavaScript’s safe-integer range:

{"reference":9007199254740993}

Parsing and serializing it with ordinary JavaScript produces:

const input = '{"reference":9007199254740993}';
console.log(JSON.stringify(JSON.parse(input)));
// {"reference":9007199254740992}

The example is covered by the repository’s executable content checks. It demonstrates the standard JavaScript behavior, not every JSON library. Download the numeric test file to compare the formatter you use.

Valid syntax does not mean an exact value

JSON syntax permits this number. JavaScript’s usual Number representation cannot distinguish every integer at that magnitude. Its maximum safe integer is 9007199254740991. Some larger integers remain representable, but adjacent integers may collapse to the same value. The whole larger range cannot be treated as exact.

A formatter can therefore report valid JSON and still change a reference. Grammar validation and preservation of application data are separate checks. This matters for database IDs, event sequences, and other values copied through a parser. See Number.MAX_SAFE_INTEGER.

Use a string before precision is lost

When the value is an identifier, agree on a string representation with the receiving application:

{"reference":"9007199254740993"}

Download the string version. Parsing and serializing this document preserves the digits as text. Do not silently change a field if its API schema requires a number; resolve the contract with the system owner.

Make the change before any lossy parsing. Quoting an already rounded result merely saves the wrong value as text. Keep the original response or file outside the formatter when investigating a discrepancy.

BigInt cannot reverse rounding

BigInt("9007199254740993").toString();
// "9007199254740993"
BigInt(JSON.parse("9007199254740993")).toString();
// "9007199254740992"

The second expression converts a Number after it has lost precision. BigInt cannot determine the original digits. Ordinary JSON.stringify also needs custom handling to serialize BigInt values. Choose a documented interchange representation, such as a decimal string, and implement it consistently.

For exact arithmetic, choose an appropriate parser and numeric type. Do not patch raw JSON with a quick regular expression: quoted strings, escapes, decimals, and exponent notation make blind replacement unreliable. Test the full round trip through every system that reads or writes the value.

How to check ToolZone output

The current JSON Formatter uses standard JavaScript parsing and serialization. It formats ordinary JSON but is not a lossless editor for every numeric token. Try the numeric and string samples above and compare both with the raw input.

  1. Keep the original text.
  2. Confirm whether identifiers should be strings in your schema.
  3. Look for long numeric literals before passing them through JavaScript tools.
  4. Compare representative identifiers and amounts afterward.
  5. If exact values change, stop using that output and fix the representation or parser.

Text Diff Checker can reveal changed digits in a small sample, but indentation changes add noise. Production imports need exact-value tests and schema validation as well as readable formatting.

Does minifying avoid rounding?

Only if the minifier preserves numeric tokens without parsing and rewriting their values. A parse-and-stringify minifier has the same problem.

What about decimal amounts?

Decimal fractions have separate binary floating-point representation concerns, even far below the large-integer boundary. Choose precision and scale according to the application’s requirements.

Is scientific notation safer?

It changes how a number is written, not the parser’s storage precision. Test the actual value after parsing.

Report a correction · Content standards