> The number of values between the two is 0x3f800000 - 0x00000000 == 0x3f800000
This should be corrected to:
> The number of values between the two is 0x3f800000 - 0x00000000 == 0x3f800001
In general, the number of numbers in the closed integral interval [a, b] is not b-a, but 1+b-a. For example, the closed interval [0,10] contains 11 integers, not 10.
(The above assumes that the original question assumes the floating point number -0 to be outside of [0,1]. Otherwise, you'll have to add 1 more.)
Source: brute force counting in a small C program.
Naturally, this might not scale to 64-bits, unless you have lots of time and computing power to spare.
One little note, is that I would disagree with your correction.
> This should be corrected to:
> > The number of values between the two is 0x3f800000 - 0x00000000 == 0x3f800001
I think the value originally computed was correct. It would make more sense to correct the wording rather than just the computed value.
i.e.
> The number of values in the range [0x00000000, 0x3f800000] is 0x3f800000 - 0x00000000 + 1 == 0x3f800001
[1]: https://en.wikipedia.org/wiki/Off-by-one_error#Fencepost_err...
This is not so surprising once you realize that this just means you have the same precision for 1/x as for x, which makes a lot of sense for scientific calculations.
f(x) = 1/x takes takes numbers in the range (-1, 1) to numbers outside that range, and vice versa. The representable floats are split evenly between those two sets
One minor nitpick: f(x)=1/x maps [-1,1] to [-inf,-1]u[+1,+inf] ... that is, 1 and -1 are in both sets and mapped onto themselves. However, this detail doesn't affect the argument much.
See my other posting for more details: https://news.ycombinator.com/item?id=13772578
This is easy to work out yourself if you remember one basic, handy property of floats: adjacent floats are adjacent in bit representation, except -0.0f and 0.0f.
For example, 0x00000000 is +0.0f. 0x00000001 is the smallest non-zero positive float. 0x00000002 is the second smallest.
The only exception to this is -0.0f and +0.0f, which are 0x80000000 and 0x00000000. The rule works with denormal floats, normal floats, and even right on the line between the two. If you want the next positive float, you always just add 0x00000001.
Now, +1.0f happens to be 0x3f800000. Recall +0.0f is 0x00000000. The number of values between the two is 0x3f800000 - 0x00000000 == 0x3f800000. Write that in decimal and you get 1065353216.