3

I know that in general two floats must be compared like abs(f1-f2) < 1e-6, but if they are rounded before comparison is it safe to compare their rounded values for equality in Python?

if round(f1,5)==round(f2,5):
    print "equal"
else
    print "unequal"

Thanks

0

2 Answers 2

4

First, it is not necessary to compare two floats with an error tolerance as you suggest. The relationship between two floating-point numbers depends on how they were derived, and that varies hugely between applications. There is no uniform answer for this.

Second, the equality-comparison of two rounded values will return true if and only if the values are equal. Allowing any sort of tolerance to get an “approximately equals” function will have no effect (if the tolerance is less than the rounding distance).

However, rounding values in floating-point is problematic because small errors may move a value from one side of a rounding point to another. For example, consider rounding f1 to the nearest integer, where f1 is some value you have computed with floating-point operations that included rounding errors. (Rounding errors occur when a mathematical result of an operation is not exactly representable, so the computer has to round it to the nearest representable result.) If f1 is very near, say, 2.5, what should it round to? Obviously, if it is less than 2.5, it will round to 2, and if it is greater, it will round to 3. But suppose the ideal value for f1, calculated with exact mathematics, is slightly greater than 2.5, but the computed value is slightly less than 2.5, due to rounding errors. Then f1 will round to 2, but we would have preferred it to round to 3.

At the same time, suppose you have an f2 that correctly rounds to 3. If you compare the rounded f1 to the rounded f2, they will be unequal.

So, after you have rounded numbers, it is too late to consider what errors might have been in them; that information is gone. Comparing numbers after they are rounded cannot tell you whether the exact mathematical results would have been close to each other before rounding.

The solution for this depends on your particular application and how the numbers are calculated. There is no general solution.

Sign up to request clarification or add additional context in comments.

4 Comments

Could you point out any case where usage of exact comparison of floating point numbers would be reasonable (unless we are checking for degenerate cases like NaN or INF, of course)?
@AlexErofeev See integers as floating point.
@AlexErofeev: Clipping. You are about to calculate an arcsine, and must either use complex arithmetic or process an exception if the argument is outside [-1, 1]. Or you are working with objects in a simulation or in graphics and want to discard objects outside a boundary. Or you are converting to decimal (somebody has to write printf) and need to know if there are more digits or not. In these cases, it makes sense to compare exactly to a precise, fixed boundary.
@AlexErofeev: In other cases, where an application has two numbers with some unknown errors in them, it is impossible to compare for ideal equality. That is, it is impossible to answer the question “If these had been calculated with exact mathematics, would they be equal?” It is impossible because the information is gone. You can only decide to accept different numbers as equal at the cost of not accepting different numbers as unequal. The allowable difference varies from application to application, and, in some, no difference is acceptable. There is no uniform answer.
1

No. As said in documentation,

The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68.

So the answer is still floating-point number and we can't have any guarantee on its exact value.

There are examples where round() returns number, that can't be represented exactly as floating-point numbers and result still needs to use epsilon for proper comparison ( round() in Python doesn't seem to be rounding properly , for example)

10 Comments

round() in Python works perfectly well. What do you mean when you say it isn't rounding properly?
@DavidHeffernan it's not an issue of Python, it's common among any IEEE 754 - based representation of floating-point numbers. Some examples are here - docs.python.org/2/tutorial/floatingpoint.html#tut-fp-issues
But that's not what you said. What you mention in that comment is just the well known fact that not all real numbers are representable on a finite computer. But you actually claim that round() does not work properly. I suggest you edit your answer to say what you mean.
@DavidHeffernan Fixed accents in the answer, hope it's ok now.
It is not correct that you cannot have a guarantee on the exact value of a floating-point number. IEEE 754 specifies floating-point numbers and arithmetic, and the results are reproducible when properly implemented.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.