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.
The correct answer is 1,065,353,217. You have an off-by-one error in the following line of argument:
> 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.)
I'll not endorse your actual line of argument, but without knowing much about the internals of a 32-bit float, I can confirm that your final answer is correct.
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.
I was under the impression (after several thousand attempts) that the correct answer is infinity, limited only by your addressable memory and bitspace.
The discrepancy with the number in the article is that you're including 2^23 mantissae with exponent 0. In any case, the interesting bit is that half of floats are in the interval [-1, 1].
> the interesting bit is that half of floats are in the interval [-1, 1]
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.
I'll clarify mostly for my sake (I hadn't thought about this before)
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.
Why 3 more? Grandparent already counted one of the border points, so the correct number is either 1 more or 2 more, depending on whether you consider the floating point number -0 to be in the closed interval [0,1] or not.
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.