In the article http://floating-point-gui.de/errors/comparison/, a method for comparing floating-point numbers is suggested:
There is an alternative to heaping conceptual complexity onto such an apparently simple task: instead of comparing a and b as real numbers, we can think about them as discrete steps and define the error margin as the maximum number of possible floating-point values between the two values.
This is conceptually very clear and easy and has the advantage of implicitly scaling the relative error margin with the magnitude of the values. Technically, it’s a bit more complex, but not as much as you might think, because IEEE 754 floats are designed to maintain their order when their bit patterns are interpreted as integers.
So instead of some complex variant of abs(b - a) < ε, we interpret a and b as integers and find abs(b - a) < ε(steps(a, b)) where ε is somehow variable with regards to the density of floating-point numbers in the vicinity of a and b. But how exactly?
Also, does this method really alleviate checking for NaNs and Infs? Or are some of these "heaps of conceptual complexity" inevitable if you want a solid, generic method of floating-point comparison?
The following C code produces 1677722
:
#include <stdio.h>
int main(int argc, char *argv[])
{
double x, y, z, a, b;
int steps;
sscanf("0.1", "%f", &x);
sscanf("0.2", "%f", &y);
sscanf("0.15", "%f", &z);
a = x + y;
b = z + z;
steps = *(int*)&b - *(int*)&a;
printf("%d\n", steps);
}
Edit: Rephrased so the word "discrete" is not misused. Rewrote "steps(a, b) < ε(a, b)" into "abs(b - a) < ε(steps(a, b))" to indicate that it may still just be floating-point operations, but that ε is chosen variably.