[Python-ideas] Way to check for floating point "closeness"?

Steven D'Aprano steve at pearwood.info
Thu Jan 15 01:04:17 CET 2015

On Wed, Jan 14, 2015 at 03:18:17PM -0600, Ron Adam wrote:
> On 01/14/2015 04:39 AM, Steven D'Aprano wrote:
> >Suppose you have a value which should be exactly 0.5, but you calculate
> >it as 0.51. Then the absolute error is 0.51-0.5 = 0.01, and the relative
> >error is 0.01/0.5 = 0.02 (or 2%).
> >
> >But consider two values, 0.0 and 0.1. Then the absolute error is 0.1-0.0
> >= 0.1, and the relative error is 0.1/0.0 which is infinite.
> >
> >So 0.0 and -0.0 are problematic when dealing with relative errors.
> I'm not sure why, but it seems like something here is out of place to me. 
> Either it's not something that would come up, or it's something you would 
> expect and handle differently.  Or it's would be an error, signalling you 
> need to handle it differently.

You're going to have to explain what you think is "out of place".

Of course doing division by zero is an error. The whole point of this 
discussion is that you cannot talk about errors relative to zero. At 
zero, you can still have an absolute error, but you cannot have a 
relative error. The definition of the error between two numeric values:

def abserr(a, b):
    return abs(a - b)

def relerr(a, b):
    return abs(a - b)/min(abs(a), abs(b))

If either a or b is zero, relarr() fails. This is a mathematical 
limitation, not a bug to be fixed.

> >>>So isn't the issue about any n distance from any floating point number 
> >>that
> >>>is less than 1 ulp?  And in that regard, comparison to zero is no 
> >>different
> >>>than any comparison to any other floating point value?
> >No. 1 ULP (Unit In Last Place) is the smallest possible difference
> >between two floats. A difference of 0 ULP means the two floats are
> >exactly equal.
> A difference of 0 ULP means they *may* be exactly equal.  The 
> calculation/representation just can't resolve to a finer amount, so two 
> figures less than 1 ULP apart can get the same floating point 
> representation.  The two numbers still have a +- error.  Possibly +-.5 ULP. 
>  ie... potentially 1 ULP apart.

I'm referring specifically to errors between two floats, not between a 
float and a theoretical exact real number. Sorry if that was not clear.

E.g. there are two consecutive floats, 5e-324 and 1e-323, which are 1 
ULP apart. But there is no such thing as a float for 8e-324. If you have 
some pencil and paper calculation which comes to 8e-324, then the error 
between that real value and either of those two floats is about 0.5 ULP.


More information about the Python-ideas mailing list