Search code examples
pythonprintingequivalent

why aren't these floats evaluated as equal?


In the following code, if x0 == x1 and y0 == y1, then it should tell me so. In the example I'm using, they are. However, Python is only saying the x values are equal, not the y.

Here's the code:

print "arc2x0 = ", arc2x0, ", arc2x1 = ", arc2x1
print "arc2y0 = ", arc2y0, ", arc2y1 = ", arc2y1

if arc2x0 == arc2x1:
    print "x0 == x1"
else:
    print "x0 != x1"

if arc2y0 == arc2y1:
    print "y0 == y1"
else:
    print "y0 != y1"

And here's the output:

arc2x0 =  5 , arc2x1 =  5.0
arc2y0 =  -4.16026900507 , arc2y1 =  -4.16026900507
x0 == x1
y0 != y1

Any idea why the y values are testing as equal? These values are calculated in the same way. Maybe there's more precision beyond what I'm seeing that isn't equal? Any way to print that precision or any other ideas on how to debug this?


Solution

  • Yes there is more precision beyond what you're seeing. The problem is that the == operator should not usually be used with floats. Floating point numbers have limited precision and accumulate rounding error, and imprecision from not being able to store all decimal values precisely. e.g.

    >>> print '%.18f' % 0.1
    0.100000000000000006
    
    >>> 0.4 - 0.3 == 0.1
    False
    

    The best way to compare floats for equality is to compare if they are nearly equal:

    def nearly_equal(x, y, epsilon=1e-7):
        return abs(x - y) < epsilon
    

    By comparing if the difference between floats is less than an epsilon value, which indicates how close is considered close enough to be equal.

    You can always use the decimal.Decimal type to avoid these problems.