I've been writing a simple verifier for C over the last few months and one of the Yak Shaving libraries I needed to write was a proper range handling library.
Since the C programs I'm writing won't be using floating point types, I got lucky - because they are an absolute pain to deal with with any degree of certainty.
A float can represent some of its range with more accuracy, and some with much less accuracy. The tradeoff could be tuned (there's probably libraries to implement that already im ignorant of).
Is that a 3rd interpretation? Has the whole argument gone so meta already that its mostly a definitions fight?
Edit: this makes me recall the "rounding flag" [1] and hitting an instance where the hardware was set to do something i hadn't expected. Meta-discussion about the nature of "accuracy" ensued then too.
Alternatively, look for fixed point numbers (though usually that's easy enough to just do manually by switching to a smaller unit, e.g. by using numbers in cents or millivolts or whatever)
> À float can represent some of its range with more accuracy, and some with much less accuracy.
IEEE floats are guaranteed to _do_ that. They’re not distributed evenly across their range, so the absolute error of replacing a real by the closest float will vary across their range.
They also aren’t distributed evenly after taking logarithms, so the relative error of replacing a real by the closest float will also vary across their range.
(That is unavoidable for the reals if you want to represent zero or negative numbers)
While it is right that errors are not represented evenly even on a logarithmic scale, it is still a useful approximation to make.
In fact the integer value of the binary representation of a float approximates crudely the logarithm of the float. This was used in Quake's famous inverse square root approximation
In my free time I'm writing a type system for the BEAM virtual machine. Like dialyzer, it features integer ranges. It, however, adds new types like literal lists, minimum-size tuples, literal strings, and subtractive types. I considered adding floating point ranges, but decided against it, mostly knowing just how hard it is having worked on John Gustafson's unums project.
a total ordering doesn't necessarily carry any semantic meaning and is not really what we care about here. We want semantically important ranges, to be able to check domains and ranges of float-valued functions (for example, arcsin, arccos, 1/x, etc.)
For a set to have a range that set must have a total order defined. If we want to find the range of a datatype we need to have a total ordering of all the possible values of that datatype. Total ordering is very relevant to the question at hand.
yes, total ordering the concept is relevant, but any given total order is not necessarily relevant. You could make a total order that goes 0.0, 1.0, 0.5, 0.75, 0.33, 0.56, 0.77, ... and that would NOT be useful for ranges.
In particular, the using IEEE order and building a range contaning NaNs is not semantically useful. Another detail is the distinction between -0.0 and 0.0; if you naively use the IEEE ordering to construct a type system you will have some problems with for example clopen ranges (-0.0, 0.0] and [-0.0, 0.0)
Why is defining negative zero equal to positive zero confusing? Because -0 < 0? That's to ensure there's total ordering - if they're equal (but not "identical"), you need some definition on ordering them.
I can understand the confusion many have with NaN, but the idea is that it's not a number, so it's not equal to anything in a number-like type.
The post mentions from_chars specifically, and the quote about the range is about that function. That means we need to ask the question whether NaN is "in the range representable by the type of value" too. For most other functions I would agree with you as NaN would be called out as a special case, and we have a meaningful range for all non-NaN values, but for from_chars I do not think "semantically important ranges" gets us there.
I also used that famous Fantasia clip to demonstrate infinite loops.
One day I'd love to create a YouTubs series where I teach computer science entirely with popculture references. Don't have the video editing skills for it, so if anyone wants to collaborate on this let me know :)
27 comments
[ 5.6 ms ] story [ 77.0 ms ] threadSince the C programs I'm writing won't be using floating point types, I got lucky - because they are an absolute pain to deal with with any degree of certainty.
It's being written for a new OS kernel.
Is that a 3rd interpretation? Has the whole argument gone so meta already that its mostly a definitions fight?
Edit: this makes me recall the "rounding flag" [1] and hitting an instance where the hardware was set to do something i hadn't expected. Meta-discussion about the nature of "accuracy" ensued then too.
[1] https://www.keil.com/support/man/docs/armlib/armlib_chr13589...
Look for the word BigFloat in your choice of language. For an alternate spin, look for a "rational number" library in your choice of language.
IEEE floats are guaranteed to _do_ that. They’re not distributed evenly across their range, so the absolute error of replacing a real by the closest float will vary across their range.
They also aren’t distributed evenly after taking logarithms, so the relative error of replacing a real by the closest float will also vary across their range.
(That is unavoidable for the reals if you want to represent zero or negative numbers)
In fact the integer value of the binary representation of a float approximates crudely the logarithm of the float. This was used in Quake's famous inverse square root approximation
Using that the range of an IEEE-754 float is from -NaN to NaN
For a set to have a range that set must have a total order defined. If we want to find the range of a datatype we need to have a total ordering of all the possible values of that datatype. Total ordering is very relevant to the question at hand.
In particular, the using IEEE order and building a range contaning NaNs is not semantically useful. Another detail is the distinction between -0.0 and 0.0; if you naively use the IEEE ordering to construct a type system you will have some problems with for example clopen ranges (-0.0, 0.0] and [-0.0, 0.0)
I don't see how there's a problem with a range containing NaN. It's no weirder than a range containing infinity.
That's alone makes it rather weird
I can understand the confusion many have with NaN, but the idea is that it's not a number, so it's not equal to anything in a number-like type.
If I do parseFloat("1e-9999") I expect the result to be 0, and maybe there is a flag or additional return value saying it's approximate.
To keep things interesting, I would demonstrate computer science concepts with clips from popular movies.
When discussing integer overflows, I would use this Ali G clip: https://youtu.be/eB5VXJXxnNU?t=53
I also used that famous Fantasia clip to demonstrate infinite loops.
One day I'd love to create a YouTubs series where I teach computer science entirely with popculture references. Don't have the video editing skills for it, so if anyone wants to collaborate on this let me know :)
For C++ there's a nice boost::numeric::interval library that handles it.
https://www.boost.org/doc/libs/1_66_0/libs/numeric/interval/...