# Definition of FLT_EPSILON

Pascal Cuoq - 9th May 2013## Correct and wrong definitions for the constant FLT_EPSILON

If I google “FLT_EPSILON”, the topmost result is this page with this definition:

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.