4 ms·
The correct answer is 1,065,353,216. This is easy to work out yourself if you remember one basic, handy property of floats: adjacent floats are adjacent in bit
by mtklein 10y ago
The correct answer is 1,065,353,216.
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.
- digga3000 10y agothe question is [0, 1] so wouldn't that include +/-0 and 1, so 3 more?
- jacobolus 10y agoProbably shouldn’t include –0, which is used to represent underflow of negative numbers.
- nine_k 10y ago-0 is "below zero, but for so little that we cannot represent", so it's outside [0, 1].
- kr7 10y agoThough for the purposes of comparisons, -0 and +0 are the same in IEEE 754. So the expression "x >= 0.0f && x <= 1.0f" is true for x = -0.
- vog 10y agoWhy 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. See my other posting for more details: https://news.ycombinator.com/item?id=13772578 https://news.ycombinator.com/item?id=13772578
- surement 10y agoThe 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].
- vog 10y ago> 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.
- gugagore 10y agoI'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
- vog 10y agoYes, that was exactly my line of thinking. 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.
- vog 10y agoThe 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.)
- lightedman 10y agoI was under the impression (after several thousand attempts) that the correct answer is infinity, limited only by your addressable memory and bitspace.
- afandian 10y agoI think people are assuming IEEE 754 floating point (as per the article). Your memory is finite, 32 bits. https://en.wikipedia.org/wiki/Floating_point https://en.wikipedia.org/wiki/Floating_point
- AimHere 10y agoI'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.
- Lanzaa 10y agoThis type of off-by-one error is so common it has its own name: fencepost error[1]. 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_error https://en.wikipedia.org/wiki/Off-by-one_error#Fencepost_err...