# Definition of FLT_EPSILON

Pascal Cuoq - 9th May 2013

## Correct and wrong definitions for the constant FLT_EPSILON

```FLT_EPSILON the minimum positive number such that 1.0 + FLT_EPSILON != 1.0.
```

No no no no no.

I don't know where this definition originates from but it is obviously from some sort of standard C library and it is wrong wrong wrong wrong wrong. The definition of the C99 standard is:

the difference between 1 and the least value greater than 1 that is representable in the given floating point type b^(1−p)

The GNU C library gets it right:

FLT_EPSILON: This is the difference between 1 and the smallest floating point number of type float that is greater than 1.

## The difference

On any usual architecture with the correct definition FLT_EPSILON is `0x0.000002p0` the difference between `0x1.000000p0` and the smallest float above it `0x1.000002p0`.

The notation `0x1.000002p0` is a convenient hexadecimal input format introduced in C99 for floating-point numbers. The last digit is a `2` where one might have expected a `1` because single-precision floats have 23 explicit bits of mantissa and 23 is not a multiple of 4. So the `2` in `0x1.000002p0` represents the last bit that can be set in a single-precision floating-point number in the interval [1…2).

If one adds FLT_EPSILON to `1.0f` one does obtain `0x1.000002p0`. But is it the smallest `float` with this property?

```#include <stdio.h>
void pr_candidate(float f)
{
printf("candidate: %.6a\tcandidate+1.0f: %.6a"  f  1.0f + f);
}
int main(){
pr_candidate(0x0.000002p0);
pr_candidate(0x0.000001fffffep0);
pr_candidate(0x0.0000018p0);
pr_candidate(0x0.000001000002p0);
pr_candidate(0x0.000001p0);
}
```

This program compiled and executed produces:

```candidate: 0x1.000000p-23	candidate+1.0f: 0x1.000002p+0
candidate: 0x1.fffffep-24	candidate+1.0f: 0x1.000002p+0
candidate: 0x1.800000p-24	candidate+1.0f: 0x1.000002p+0
candidate: 0x1.000002p-24	candidate+1.0f: 0x1.000002p+0
candidate: 0x1.000000p-24	candidate+1.0f: 0x1.000000p+0
```

No `0x0.000002p0` is not the smallest number that added to `1.0f` causes the result to be above `1.0f`. This honor goes to `0x0.000001000002p0` the smallest float above half FLT_EPSILON.

Exactly half FLT_EPSILON the number `0x0.000001p0` or `0x1.0p-24` as you might prefer to call it causes the result of the addition to be exactly midway between `1.0f` and its successor. The rule says that the “even” one has to be picked in this case. The “even” one is `1.0f`.

## Conclusion

Fortunately in the file that initiated this rant the value for FLT_EPSILON is correct:

```#define FLT_EPSILON 1.19209290E-07F // decimal constant
```

This is the decimal representation of `0x0.000002p0`. Code compiled against this header will work. It is only the comment that's wrong.

Pascal Cuoq
9th May 2013