FracturedJson icon indicating copy to clipboard operation
FracturedJson copied to clipboard

Formatting of numbers

Open potetball opened this issue 2 years ago • 5 comments

image

Hey, I tested your formatter, and discovered the number rounding, wondering if that is intended feature: 5317062322949193729 becomes 5317062322949194000

potetball avatar May 04 '22 14:05 potetball

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.

shuckster avatar May 04 '22 15:05 shuckster

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!

j-brooke avatar May 04 '22 15:05 j-brooke

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 avatar May 04 '22 15:05 j-brooke

@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 avatar May 04 '22 17:05 shuckster

@shuckster Good thought. I hadn't known that the "reviver" parameter existed. Pity it doesn't look like it helps in this case.

j-brooke avatar May 04 '22 18:05 j-brooke

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.)

j-brooke avatar Oct 07 '22 14:10 j-brooke