
On Tue, Jan 27, 2015 at 12:57:03PM -0500, Alexander Belopolsky wrote:
Just as a point of reference, APL and its derivatives use tolerant comparison in the default equal (=) operator. The definition that they use for finite x and y is simply
x = y <=> abs(x-y) <= tol * max(abs(x), abs(y))
That's essentially the same as Bruce Dawson recommends: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-number... and also the approx_equal function in test_statistics, except that also uses an absolute error if given. Guido has asked what the use case for giving both relative and absolute error. I'll quote Dawson from the link above: [quote] The most generic answer to this quandary is to use a mixture of absolute and relative epsilons. If the two numbers being compared are extremely close – whatever that means – then treat them as equal, regardless of their relative values. This technique is necessary any time you are expecting an answer of zero due to subtraction. The value of the absolute epsilon should be based on the magnitude of the numbers being subtracted – it should be something like maxInput * FLT_EPSILON. Unfortunately this means that it is dependent on the algorithm and the inputs. Charming. The ULPs based technique also breaks down near zero for the technical reasons discussed just below the definition of AlmostEqualUlps. Doing a floating-point absolute epsilon check first, and then treating all other different-signed numbers as being non-equal is the simpler and safer thing to do. Here is some possible code for doing this, both for relative epsilon and for ULPs based comparison, with an absolute epsilon ‘safety net’ to handle the near-zero case: [...] [end quote] -- Steven