FracturedJson
FracturedJson copied to clipboard
Formatting of numbers
Hey, I tested your formatter, and discovered the number rounding, wondering if that is intended feature: 5317062322949193729 becomes 5317062322949194000
This is because your number is greater than Number.MAX_SAFE_INTEGER
.
You could present your numbers only as strings and use a library like bignumber.js to work with them, or you could use the BigInt number-type and suffix your numbers with n
.
Interesting. This is happening because the JavaScript version reads the document as JS data, before trying to produce output. In other word, it relies on JSON.parse
. All numbers in JavaScript are double-precision floats, and therefore limited to 52 bits of precision (roughly 16 decimal digits).
Based on some quick tests, it looks like the .NET version does not exhibit this behavior.
The JSON spec doesn't put any limit on the size or precision of a number in a document. In theory you could have a JSON number with 1,000 digits. (It does warn about interoperability problems outside the range of doubles, though.) The correct behavior would be to preserve the number exactly, no matter how many digits it has. So I think it's fair to say this is a bug in the JavaScript/Browser implementations.
As a practical matter, I can't fix this without rewriting the JavaScript version using a more powerful JSON parsing library, which would more closely follow how the C# code works. I might do that at some point, since it would open up a few other requested features. But that's a rewrite, not a patch. In the short term I think I need to flag this as a known issue. Hopefully it doesn't impact too many people.
(edit) Forgot to mention: Thanks for pointing this out!
This is because your number is greater than
Number.MAX_SAFE_INTEGER
.You could present your numbers only as strings and use a library like bignumber.js to work with them, or you could use the BigInt number-type and suffix your numbers with
n
.
An approach like that would work if I were processing the numbers individually. But since I'm going through JSON.parse
, the damage has already been done before I start working with it.
In the .NET code there's some logic to check for whether a column/array of numbers can be sensibly formatted. If not, it just copies the number element as a string, from the input to the output. I think I'd want to mimic that behavior, if I were to rewrite the JS version.
@j-brooke I did wonder if the JSON.parse "reviver" callback could help, but you're quite right - I ram quick test and the number is indeed clobbered before it reaches the callback.
Also, it seems that BigInt isn't a supported JSON number type? At least it wasn't working for me. 🤔
@shuckster Good thought. I hadn't known that the "reviver" parameter existed. Pity it doesn't look like it helps in this case.
Version 3 of the Web Formatter is up, and this problem is fixed there. (The JS and VSCode versions haven't been updated yet though.)