C++ – How to Subtract a Very Small Number from a Float in C++

c++

The smallest number that differentiates two float values is FLT_EPSILON, which is defined as:

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

(Yes I am aware of this: https://frama-c.com/2013/05/09/Definition-of-FLT_EPSILON.html)

However, upon subtracting a very small number (1e-12) from a zero, I would expect the resulting number to be zero, also considering it is less than half way mark of FLT_EPSILON.

However, the following program outputs:

Value of EPSILONF: -0.000000000001000

#include <stdio.h>
    
#define EPSILONF static_cast<float>(1e-12)
    
int main() {
    printf("Value of EPSILONF: %.15f\n", float(0.0f-EPSILONF));
    return 0;
}

What am I missing here?

Best Answer

The smallest number that differentiates two float values is FLT_EPSILON

What you are missing is that this isn't what FLT_EPSILON is. FLT_EPSILON is the difference between 1.0 and the next representable number greater than 1.0.

Once the absolute value gets close to 0 you get into the range of subnormal numbers (see page 19), where the differences between two consecutive representable numbers are significantly smaller than FLT_EPSILON.

The difference (effectively) between 0.0 and the next greatest representable number is FLT_MIN. For a 32-bit IEEE floating-point it's 2-149.

Btw, for doubles, the constants are DBL_EPSILON and DBL_MIN.