I thought the JSON spec was that a number is of any precision and that it’s up to the parser to say, “best I can do is 754.”
That is, I think you can deserialize very long decimal numbers to higher accuracy in some languages.
151–160 of 179 posts
I thought the JSON spec was that a number is of any precision and that it’s up to the parser to say, “best I can do is 754.”
That is, I think you can deserialize very long decimal numbers to higher accuracy in some languages.
> NaN/infinity values can propagate and cause chaos NaN is the most misunderstood feature of IEEE floating point. Most people react to a NaN like they'd react to the dentist telling them they need a root canal. But NaN is actually a very valuable and useful tool! NaN is just a value that represents an invalid floating point value. The result of any operation on a NaN is a NaN. This means that NaNs propagate from the…
Loud and clear on the other point. I work with ROS a lot and the message definitions do not support NaN or null. So we have these magic numbers all over the place for things like “the robot does not yet know where it is.” (therefore: on the moon.)
Example 4 mentions that the result might be different with the same code. Here is an example that is particularly counter-intuitive. Some CPU have the instruction FMA(a,b,c) = ab + c and it is guaranteed to be rounded to the nearest float. You might think that using FMA will lead to more accurate results, which is true most of the time. However, assume that you want to compute a dot product between 2 orthogonal vecto…
Note that with gcc/clang you can control the auto-use of fma with compile flags (-ffp-contract=off). It is pretty crazy imho that gcc defaults to using fma
> NaN/infinity values can propagate and cause chaos NaN is the most misunderstood feature of IEEE floating point. Most people react to a NaN like they'd react to the dentist telling them they need a root canal. But NaN is actually a very valuable and useful tool! NaN is just a value that represents an invalid floating point value. The result of any operation on a NaN is a NaN. This means that NaNs propagate from the…
> But let's study it a bit. Suppose you are searching an array for a value, and the value is not in the array. What do you return for an index into the array? People often use -1 as the "not found" value. But then what happens when the -1 value is not noticed? It winds up corrupting further attempts to use it. The problem is that integers do not have a NaN value to use for this. You return (value, found), or (value,e…
And this is great for environments that can support it, but as the levels get lower and lower, such safety nets become prohibitively expensive.
Take data formats, for example. Say we have a small device that records ieee754 binary float32 readings. A simple format might be something like this:
record = reading* terminator;
reading = float(32, ~) | invalid;
invalid = float(32, snan);
terminator = uint(32, 0xffffffff);
We use a signaling NaN to record an error in the sensor reading, and we use the encoding 0xffffffff (which is a quiet NaN) to mark the end of the record.If we wanted the validity signaling to be out-of-band, we'd need to encode it as such; perhaps as a "validity" bit preceding each record:
record = reading* terminator;
reading = valid_bit & float(32, ~);
valid_bit = uint(1, ~);
terminator = uint(1, 1) & uint(32, 0xffffffff);
Now the format is more complicated, and we also have alignment problems due to each record entry being 33 bits. We could use a byte instead and lose to bloat a little: record = reading* terminator;
reading = valid_bit & float(32, ~);
valid_bit = uint(8, ~);
terminator = uint(8, 1) & uint(32, 0xffffffff);
But we're still unaligned (40 bits per record), which will slow down ingestion. We could fix that by using a 32-bit validity "bit": record = reading* terminator;
reading = valid_bit & float(32, ~);
valid_bit = uint(32, ~);
terminator = uint(32, 1) & uint(32, 0xffffffff);
But now we've doubled the size of the data format.Or perhaps we keep it as a separate bit array, padded to a 32-bit boundary to deal with alignment issues:
record = bind(count,count_field) & pad(32, validity{count.value}, padding*) & reading{count.value};
count_field = uint(32,bind(value,~));
reading = float(32, ~);
validity = uint(1, ~);
padding = uint(1, 0);
But now we've lost the ability of ad-hoc appends (we have to precede each record with a length), and the format is becoming a lot more complicated.> NaN/infinity values can propagate and cause chaos NaN is the most misunderstood feature of IEEE floating point. Most people react to a NaN like they'd react to the dentist telling them they need a root canal. But NaN is actually a very valuable and useful tool! NaN is just a value that represents an invalid floating point value. The result of any operation on a NaN is a NaN. This means that NaNs propagate from the…
> But let's study it a bit. Suppose you are searching an array for a value, and the value is not in the array. What do you return for an index into the array? People often use -1 as the "not found" value. But then what happens when the -1 value is not noticed? It winds up corrupting further attempts to use it. The problem is that integers do not have a NaN value to use for this. You return (value, found), or (value,e…
Earlier quoted context omitted.
> If you knew more about the details of binary64 aka float64, you could confidently say that "2.3" means 2.29999995231628417969 […]" Then I think writing let f = 2.3; Should be a compile error. The compiler should force you to write the “snapped” value in order to not mislead. :)
Now try writing the "snapped" value for 2.3 as a finite decimal. :-)
Earlier quoted context omitted.
This is surprising to me! Can you explain what problems you encountered? My (limited) understanding is that the main effect of fast-math is to turn off support for subnormals. Since subnormals are only used to represent extremely small values, I wouldn't expect them to have much effect in the real world.
fast-math can result in many things you may not expect, e.g. treating FP operations as being associative and distributive, which they aren’t.