Неинтуитивное поведение при сравнении больших чисел - PullRequest
1 голос
/ 08 апреля 2019

Только что обнаружил некоторое неинтуитивное поведение во время соревнования в Google CodeJam.

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

output: True

(ок ...)

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

output: False

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

(так что, это поведение зависит от размера числа?!)

(это потому, что большие целые числа Python представлены за кулисами по-разному?)

input: True == True

output: False

(хорошо, все в порядке)

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

вывод: False

(больше ?????)

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

вывод: True

(и я полностью потерян)

1 Ответ

5 голосов
/ 08 апреля 2019

Это связано с плавающей точкой, а также с тем, как python обрабатывает результат возведения в степень, когда задействованы целые числа:

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

оператор pow сохраняет результат как целое число.

Теперь, если вы умножите на 1.0, вы заставите его изменить представление на float, а затем, с показателем 30, точности будет недостаточно для сравнения с тем же значением, что и целое число.

Не связанный, но чтобы полностью ответить на ваш вопрос, странное поведение с == не связано: это проблема цепочки операторов .Использование набора скобок не повредит и не решит вашу проблему:

>>> 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
>>> 
...