Live data from Hacker News

What even is a JSON number?

blog.trl.sn

31–40 of 151 posts

Re: What even is a JSON number?

#31
post #6

Since JSON is so widely used it should be modified to support more types - Mongo DB's Extended JSON supports all the BSON (Binary) types: Array Binary Date Decimal128 Document Double Int32 Int64 MaxKey MinKey ObjectId Regular Expression Timestamp https://www.mongodb.com/docs/manual/reference/mongodb-extend...

Or maaaybe use XML for such cases

Re: What even is a JSON number?

#32

Earlier quoted context omitted.

> That's true for every floating point number in every programming language you have ever used, though. Alright, if "you" have only ever used python. In C, for example, we have hexadecimal floating point literals that represent all floats and doubles exactly (including infinities and nans that make the json parser fail miserably).

> we have hexadecimal floating point literals that represent all floats and doubles exactly How do you do that? A couple of resources I found but which I’m not sure if are about exactly what you speak of https://stackoverflow.com/questions/65480947/is-ieee-754-rep... https://gcc.gnu.org/onlinedocs/gcc/Hex-Floats.html Furthermore, what exactly do you mean by “all floats and doubles exactly”?

Yes, I was talking about what is described in your resources. You can do this:

    // define a floating-point literal in hex and print it in decimal
    float x = 0x1p-8;          // x = 1.0/256
    printf("x = %g\n", x);     // prints 0.00390625
    
    // define a floating point literal in decimal and print it in various ways
    float y = 0.3;             // non-representable, rounded to closest float
    printf("y = %g\n", y);     // 0.3 (the %g format does some heuristics)
    printf("y = %.10f\n", y);  // 0.3000000119
    printf("y = %.20f\n", y);  // 0.30000001192092895508
    printf("y = %a\n", f);     // 0x1.333334p-2

Re: What even is a JSON number?

#33
post #15

Earlier quoted context omitted.

That's true for every floating point number in every programming language you have ever used, though. $ python3 Python 3.10.13 (main, Aug 24 2023, 12:59:26) [GCC 12.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> 100000.000000000017 100000.00000000001

> That's true for every floating point number in every programming language you have ever used, though. Alright, if "you" have only ever used python. In C, for example, we have hexadecimal floating point literals that represent all floats and doubles exactly (including infinities and nans that make the json parser fail miserably).

[deleted]

Re: What even is a JSON number?

#34
When I wrote my jsonptr tool a few years ago, I noticed that some JSON libraries (in both C++ and Rust) don't even do "parse a string of decimal digits as a float64" properly. I don't mean that in the "0.3 isn't exactly representable; have 0.30000000000000004 instead" sense.

I mean that rapidjson (C++) parsed the string "0.99999999999999999" as the number 1.0000000000000003. Apart from just looking weird, it's a different float64 bit-pattern: 0x3FF0000000000000 vs 0x3FF0000000000001.

Similarly, serde-json (Rust) parsed "122.416294033786585" as 122.4162940337866. This isn't as obvious a difference, but the bit-patterns differ by one: 0x405E9AA48FBB2888 vs 0x405E9AA48FBB2889. Serde-json does have an "float_roundtrip" feature flag, but it's opt-in, not enabled by default.

For details, look for "rapidjson issue #1773" and "serde_json issue #707" at https://nigeltao.github.io/blog/2020/jsonptr.html

Re: What even is a JSON number?

#35

Earlier quoted context omitted.

> we have hexadecimal floating point literals that represent all floats and doubles exactly How do you do that? A couple of resources I found but which I’m not sure if are about exactly what you speak of https://stackoverflow.com/questions/65480947/is-ieee-754-rep... https://gcc.gnu.org/onlinedocs/gcc/Hex-Floats.html Furthermore, what exactly do you mean by “all floats and doubles exactly”?

Yes, I was talking about what is described in your resources. You can do this: // define a floating-point literal in hex and print it in decimal float x = 0x1p-8; // x = 1.0/256 printf("x = %g\n", x); // prints 0.00390625 // define a floating point literal in decimal and print it in various ways float y = 0.3; // non-representable, rounded to closest float printf("y = %g\n", y); // 0.3 (the %g format does some heuris…

So for example if you make a variable that has the value parent commenter used

100000.000000000017

And then you print it.

Does it preserve the exact value?

Re: What even is a JSON number?

#36

I tend to end up encoding everything as an integer (multiply by 1000, 10000 etc) and then turn it back into a float/decimal on decode. For instance if I am building a system dealing with dollar amounts I will store cent amounts everywhere, communicate cent amounts over the wire, etc. then treat it as a presentation concern to render it as a dollar amount.

I often store it as smaller than cents, because anything with division or a basket of summed parts with taxes can start to get funky if you round down (and some places have laws about that.)

Re: What even is a JSON number?

#38

Earlier quoted context omitted.

Yes, I was talking about what is described in your resources. You can do this: // define a floating-point literal in hex and print it in decimal float x = 0x1p-8; // x = 1.0/256 printf("x = %g\n", x); // prints 0.00390625 // define a floating point literal in decimal and print it in various ways float y = 0.3; // non-representable, rounded to closest float printf("y = %g\n", y); // 0.3 (the %g format does some heuris…

So for example if you make a variable that has the value parent commenter used 100000.000000000017 And then you print it. Does it preserve the exact value?

Your question is ambiguous for two different reasons. First, this value is not representable as a floating-point number, so there's no way that you can even store it in a float. Second, once you have a float variable, you can print it in many different ways. So, the answer to your question is, irremediably, "it depends what you mean by exact value".

If you print your variable with the %a format, then YES, the exact value is preserved and there is no loss of information. The problem is that the literal that you wrote cannot be represented exactly. But this is hardly a fault of the floats. Ints have exactly the same problem:

    int x = 2.5;   // x gets the value 2
    int y = 7/3;   // same thing

Re: What even is a JSON number?

#39

Earlier quoted context omitted.

So for example if you make a variable that has the value parent commenter used 100000.000000000017 And then you print it. Does it preserve the exact value?

Your question is ambiguous for two different reasons. First, this value is not representable as a floating-point number, so there's no way that you can even store it in a float. Second, once you have a float variable, you can print it in many different ways. So, the answer to your question is, irremediably, "it depends what you mean by exact value ". If you print your variable with the %a format, then YES, the exact…

So in other words, is it fair to say that this situation is not much different from what you get with Python?

Re: What even is a JSON number?

#40

I tend to end up encoding everything as an integer (multiply by 1000, 10000 etc) and then turn it back into a float/decimal on decode. For instance if I am building a system dealing with dollar amounts I will store cent amounts everywhere, communicate cent amounts over the wire, etc. then treat it as a presentation concern to render it as a dollar amount.

Makes sense for dollars, but for anything like graphics or physics I'd consider a power of two like 1,024 as the fixed-point factor instead.

My intuition tells me that "x * 1000 / 1000 == x" might not be true for all numbers if you're using floats.

Post reply on HN