C++ Compare float values
We want to compare two obviously equal floating point values (something like 3.456) in C++ but we sometimes get wrong results. For example, we want to find out if a floating point number is equal to zero:
float f = sqrt(9.0f) - 3.0f; // 9²-3
if (f == 0.0f) // works only sometimes
Sometimes the variable f isn't equal to 0.0f, but due to the floating point precision it's something like 0.0000000000001f and the comparing fails.
The first thing that we need to know is that this problem would never appear with integer values. If we have "int 3" and subtract "int 3" from it, it will always be exactly "0".
The problem only happens with floating point numbers (float and double in C++), because of the way they are saved in memory. There is a lot of information about this around the web, for us it's enough if we know that this happens and what we can do about it.
To solve this problem we need a small epsilon value that defines a tolerance when comparing floating point values. There are many different versions of this algorithm, with dynamic epsilon values depending on how big the numbers are that you want to compare, or with constant epsilon values of many different sizes.
The epsilon in the following algorithm is what we came to after several years of struggling with this problem. So far it worked great, but everyone is free to choose different variations of this.
bool cmpf(float A, float B, float epsilon = 0.005f)
return (fabs(A - B) < epsilon);
Epsilon means how far they can be different from each other, while still being detected as equal. Epsilon is automatically set to 0.005f if you only pass two parameters to the function, which means you can use it like this:
Or like this if you want to set the epsilon manually:
cmpf(1.0f, 2.0f, 0.0001f);
We use the absolute value of A - B (fabs function) because A - B can be either positive or negative, which means that we would have to compare it to a positive and a negative epsilon. By using fabs, we get the absolute value which is always positive, that saves us comparing it with a negative epsilon.
Note: fabs means float absolute.
Let's see what happens if we use our cmpf function with the previously discussed example:
float f = sqrt(9.0f) - 3.0f;
if (cmpf(f, 0.0f))
It works, even when trying it out hundreds of times. That's what we wanted.
A small function with an incredibly huge impact. Always use this method to compare float or double values, otherwise your game will have random bugs in it because of the floating point precision.
A detailed article about the whole problem can be found here.
Please note that this is one of the most important problems to know about C++. A good float compare function can be found in the tool-set of every good programmer.