1

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

  • 1
    How do you figure “the relative epsilon is slightly greaer than `1e-06`”? Their **absolute** difference is 10^−6. The **relative** difference is 10^−6/1234, which is less than 10^−9. So they are within a relative “tolerance” of 10^−9, and `isclose` should return true. – Eric Postpischil May 14 '20 at 01:01
  • 1
    Re “why this formula is acceptable”: [It is not](https://stackoverflow.com/a/13941383/298225), and functions like this should not be a part of general-purpose libraries. [There is no general solution for comparing floating-point numbers that compensates for errors in previous operations.](https://stackoverflow.com/a/56040270/298225) – Eric Postpischil May 14 '20 at 01:05
  • 1
    A relative tolerance is used because the floating-point format scales using an exponent, some errors tend to be relative to the magnitude of an operation result. But this applies only for individual operations. When multiple operations are performed, error analysis becomes quite complicated. [There is an entire field of study for it.](https://en.wikipedia.org/wiki/Numerical_analysis) Generally, the rounding errors are neither absolute nor relative to the results; they are dependent on many factors, and `isclose` is useless or harmful. It may serve some role in testing, but little more. – Eric Postpischil May 14 '20 at 01:07
  • Thanks @EricPostpischil. Here is what I was referring to, I started with the formula: `max(rel_tol * max(abs(a), abs(b))` which would simplify to `1e-09`*1234.000001`. That computes to `0.000001234000001`. This is slightly greater than `1e-06`, by `2.34000001 × 10^-7`. If I made a mistake there let me know. What I still don't follow is why this formula is used. I was thinking that the documentation meant that it was accurate to the 9th decimal place, but now I read that to mean the 9 total digits of a decimal number. – DoubtingThomas3005 May 14 '20 at 01:10
  • @EricPostpischil - my first reply was written before I saw your second two comments. Thanks for the detailed answers. – DoubtingThomas3005 May 14 '20 at 01:11

1 Answers1

2

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

Sylvaus
  • 844
  • 6
  • 13