Reputation: 4142
In C using float.h I wonder how can I find the largest number that if I add to 1 the answer will remain 1.
i.e 1 + x = 1 how to find x?
Upvotes: 2
Views: 1863
Reputation: 215277
If you want "the biggest number that is smaller than FLT_EPSILON":
x = nextafterf(FLT_EPSILON, 0)
If you want the biggest number x
such that 1.0f + x == 1.0f
, then the answer depends on the rounding mode, but in the default rounding mode, it's simply FLT_EPSILON/2
.
However, things aren't quite so simple. Because of the way round-to-nearest rounds to the even neighbor on ties, you have 1.0f + FLT_EPSILON/2 == 1.0f
, but:
(1.0f+FLT_EPSILON) + FLT_EPSILON/2 != (1.0f+FLT_EPSILON)
So you may instead want to use the slightly smaller value of x
:
x = nextafterf(FLT_EPSILON/2, 0)
This will ensure that y+x == y
for any y >= 1.0
.
Upvotes: 8
Reputation: 477100
It depends on rounding modes. Here's a simple example. Suppose our precision is 4 bits, and we have some sort of IEEE754 representation. So the value 1 is stored as 1.0000 × 20. The next bigger number is 1.0001 × 20, and the machine epsilon ε is defined as the difference between the two, which is 0.0001 × 20 = 1.0000 × 2−4. Now:
ε / 2 = 1.0000 × 2−5 = 0.00001, and
ε / 4 = 1.0000 × 2−6 = 0.000001.
When you add one of the two to 1, the numbers are first rewritten for the power 20 and rounded to 4 digits after the separator. The surviving mantissa of ε / 4 is surely 0.0000, while the surviving mantissa of ε / 2 is either 0.0000 or 0.0001, depending on whether you round up or down.
As long as the effective resulting mantissa is 0.0000, you can add the number to 1 without changing its value.
(The actual precisions are 23+1, 52+1 and 64 for single, double and extended double precision floats.)
Upvotes: 3