You are correct with your observation.
If x == 0.0
, then abs(x) * epsilon
is zero and you're testing whether abs(y) <= 0.0
.
If y == 0.0
then you're testing abs(x) <= abs(x) * epsilon
which means either epsilon >= 1
(it isn't) or x == 0.0
.
So either is_equal(val, 0.0)
or is_equal(0.0, val)
would be pointless, and you could just say val == 0.0
. If you want to only accept exactly +0.0
and -0.0
.
The FAQ's recommendation in this case is of limited utility. There is no "one size fits all" floating-point comparison. You have to think about the semantics of your variables, the acceptable range of values, and the magnitude of error introduced by your computations. Even the FAQ mentions a caveat, saying this function is not usually a problem "when the magnitudes of x and y are significantly larger than epsilon, but your mileage may vary".