Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



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.


This 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_err...


I was under the impression (after several thousand attempts) that the correct answer is infinity, limited only by your addressable memory and bitspace.


I 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


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


Yes, 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.


the question is [0, 1] so wouldn't that include +/-0 and 1, so 3 more?


Probably shouldn’t include –0, which is used to represent underflow of negative numbers.


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.

See my other posting for more details: https://news.ycombinator.com/item?id=13772578


-0 is "below zero, but for so little that we cannot represent", so it's outside [0, 1].


Though 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: