As I’ve noted elsewhere, I’ve often found it frustrating that so few programmers seem to have any idea about these matters.
As some have noted above, it’s hard to choose the right epsilon when, as stated right in the OP, you can’t make any assumptions about the ranges of the numbers you’ll be looking at.
For some kinds of apps, you would know what size numbers you have. I worked with a cash register app for many years that was CHOCK FULL of comparison error bugs like this because the programmers had no clue about these things. The data consisted mostly of dollars-and-cents amounts, encoded as floating-point dollars (e.g., 7 dollars and 43 cents was the float 7.43).
A common type of comparison was: Did customer purchase 10.00 or more, to qualify for a discount? Well, a customer might well have bought exactly 10.00 of stuff but it actually added up to 9.9999999999983 so the register wouldn’t give the discount. But it sure looked like 10.00 on the receipt, since amounts were rounded to two decimal places. ETA: A similar type of comparison, with similar bugs, was common for determining sales tax threshholds, and many other kinds of threshhold cases.
The programmers got into the habit of making such comparisons by converting to a character string with two decimal places (which the conversion library automatically rounded), and comparing the character strings. In my code, however, I used the abs(a-b) < epsilon trick, for which I always used epsilon = 0.0000001
Chronos, on the other hand, pointed out that in some applications, like in his work, if your two numbers are so close together as to raise this problem, then maybe it doesn’t matter which branch the program takes. (See posts 4, 6, 13, 14, 16 for the complete conversation on that point in that thread.)