Search code examples
pythonpython-3.xmathfloating-pointfloating

Understanding Python Relative Epsilon


While handling a floating point error, I discovered the pyth math moduel's isclose method. This method calculates a relative epsilon between a and b using the following formula:

max(rel_tol * max(abs(a), abs(b))

By default, rel_tol is set to 1e-09. According to the documentation, this "assures that the two values are the same within about 9 decimal digits."

Lets consider the following example...

a=1234.000001
b=1234

# the relative epsilon, as calculated with the above formula, would be 0.000001234000001
# so math.isclose returns true
math.isclose(a,b)

Per the documentation, this seems like it should be false instead, since it's not accurate within the 9th decimal place. But as the relative epsilon is slightly greaer than 1e-06, which is the difference, it returns true. I've seen this relative epsilon formula in a few places now, but never with an explanation as to why it is used. I'm hoping to understand why this formula is acceptable, and how I can apply that to my usage of isclose. Thank you


Solution

  • You may be confusing the difference and the relative tolerance.

    You are right that the difference between a and b is 1e-6 and that the two numbers are the same only to the sixth decimal place.

    However, Python documentation is talking about decimal digits which encompasses the digits before the period. Thus the two numbers are also the same to the 9th decimal digits.

    The reason why the relative tolerance is used instead of difference is easy to see when you deal with small numbers. If all your numbers are smaller than 1e-10 and we were to use difference, we could never compare two floating numbers. But if you use relative tolerance you have a better measure of the "relative distance" between the two floating point numbers.

    About the usefulness of isclose, one example could be sensor measurement. If you write a code that waits for a signal settles to a floating point value, you don't want to test for the measurement to be equal to the desired value since it may never happen due to rounding errors but wait for the measurement to be close to the desired value.

    Hope it helps