[Python-ideas] PEP 485: A Function for testing approximate equality

Steven D'Aprano steve at pearwood.info
Fri Feb 6 01:44:07 CET 2015


On Thu, Feb 05, 2015 at 11:39:43AM -0800, Chris Barker wrote:

> > - What if a tolerance is inf or nan? What if all args are inf or nan?
> 
> 0.0 < rel_tol < 1.0)

I can just about see the point in restricting rel_tol to the closed 
interval 0...1, but not the open interval. Mathematically, setting the tolerance to 0 
should just degrade gracefully to exact equality, and a tolerance of 
1 is nothing special at all. 

Values larger than 1 aren't often useful, but there really is no reason 
to exclude tolerances larger than 1. "Give or take 300%" (ie. 
rel_tol=3.0) is a pretty big tolerance, but it is well-defined: a 
difference of 299% is "close enough", 301% is "too far".

You might argue that if you want exact equality, you shouldn't use a 
tolerance at all but just use == instead. But consider a case where 
you might be trying calculations repeatedly and decreasing the tolerance 
until it fails:

# doesn't handle termination properly
rel_tol = pick_some_number
while close_to(something, something_else, rel_tol):
    rel_tol /= 2
    
In some cases, your calculation may actually be exact, and it simplies 
the code if close_to(a, b, rel_tol) degrades nicely to handle the exact 
case rather than you needing to switch between close_to and == by hand.

Negative error tolerances, on the other hand, do seem to be meaningless 
and should be prevented.


> I've enforced this in the sample code -- it's not strictly necessary, but
> what does a negative relative tolerance mean, anyway, and a tolerance over
> 1.0 has some odd behaviour with zero and could hardly be called "close"
> anyway. Text added to make this clear.

I don't see why a tolerance over 1 should behave any more oddly with 
zero than a tolerance under 1.

And as for "close", some people would argue that rel_tol=0.5 is "hardly 
close". Sometimes you might accept anything within an order of magnitude 
the expected value: anything up to 10*x is "close enough". Or 20 times. 
Who knows? 

(E.g. "guess the number of grains of sand on this beach".) Any upper 
limit you put in is completely arbitrary, and this function shouldn't be 
in the business of telling people how much error they are allowed to 
tolerate. It's easy for people to put in their own restrictions, but 
hard for them to work around yours.


> if a and/or b are inf or nan, it follows IEE754 (which mostly "just works"
> with no special casing in the code.

That is very nice.



-- 
Steve


More information about the Python-ideas mailing list