Search code examples
pythonbooleanfloating-accuracylargenumber

Unintuitive behavior when comparing large numbers


Just found some unintuitive behavior while competing in Google CodeJam.

input: pow(10, 20) in [pow(10, 20) * 1.0]

output: True

(ok...)

input: pow(10, 30) in [pow(10, 30) * 1.0]

output: False

(???????????)

(so uh, this behavior is dependent on the size of the number?!)

(is this because big Python integers are represented differently behind the scenes?)

input: True == True

output: False

(ok, all is normal)

input: pow(10, 20) in [pow(10, 20) * 1.0] == pow(10, 20) in [pow(10, 20) * 1.0]

output: False

(more ?????)

input: pow(10, 20) in [pow(10, 20) * 1.0] and pow(10, 20) in [pow(10, 20) * 1.0]

output: True

(and I'm totally lost)


Solution

  • That's because of floating point, and also because of the way python handles the result of exponentiation when integers are involved:

    >>> type(pow(10,30))
    <class 'int'>
    

    the pow operator kept the result as integer.

    Now if you multiply by 1.0 you force it to change representation to float, and then, with a 30 exponent, the precision isn't enough to compare to the same value as integer.

    Unrelated but to fully answer your question, the strange behaviour with == is not related: it's a problem of operator chaining. Using a set of parentheses doesn't hurt and fixes your issue:

    >>> pow(10, 20) in [pow(10, 20) * 1.0] == pow(10, 20) in [pow(10, 20) * 1.0]
    False
    >>> (pow(10, 20) in [pow(10, 20) * 1.0]) == (pow(10, 20) in [pow(10, 20) * 1.0])
    True
    >>>