Когда Python выполняет преобразование типов при сравнении int и float? - PullRequest
0 голосов
/ 28 сентября 2018

Почему Python возвращает True, когда я сравниваю int и float объекты, имеющие одинаковое значение?

Например:

>>> 5*2 == 5.0*2.0
>>> True

Ответы [ 7 ]

0 голосов
/ 28 сентября 2018

Вы можете взглянуть на исходный код для реализации CPython.

Функции предшествует этот комментарий, объясняющий, как делается попытка преобразования:

/* Comparison is pretty much a nightmare.  When comparing float to float,
 * we do it as straightforwardly (and long-windedly) as conceivable, so
 * that, e.g., Python x == y delivers the same result as the platform
 * C x == y when x and/or y is a NaN.
 * When mixing float with an integer type, there's no good *uniform* approach.
 * Converting the double to an integer obviously doesn't work, since we
 * may lose info from fractional bits.  Converting the integer to a double
 * also has two failure modes:  (1) an int may trigger overflow (too
 * large to fit in the dynamic range of a C double); (2) even a C long may have
 * more bits than fit in a C double (e.g., on a 64-bit box long may have
 * 63 bits of precision, but a C double probably has only 53), and then
 * we can falsely claim equality when low-order integer bits are lost by
 * coercion to double.  So this part is painful too.
 */

Не гарантируется, что другие реализации будут следовать той же логике.

0 голосов
/ 28 сентября 2018

Из документации :

Python полностью поддерживает смешанную арифметику: когда бинарный арифметический оператор имеет операнды разных числовых типов, операнд с «более узким» типом расширяетсядругой, где обычное целое число уже длинного, а целое - меньше, чем число с плавающей запятой - сложнее.Сравнения между числами смешанного типа используют одно и то же правило.

В соответствии с этим 5 * 2 расширяется до 10,0 и равно 10,0. Если вы сравниваете смешанные типы данных, то результат будет рассмотренна основе типа данных, который имеет большой диапазон, так что в вашем случае диапазон с плавающей запятой больше, чем число int float max может быть -> 1.7976931348623157e + число 308 int max может быть -> 9223372036854775807

Спасибо

0 голосов
/ 28 сентября 2018

Оператор == сравнивает только значения, но не типы.Вы можете использовать ключевое слово «is» для достижения того же эффекта, что и использование === на других языках.Например,

5 is 5.0

возвращает False

0 голосов
/ 28 сентября 2018

Простой ответ заключается в том, что язык разработан таким образом.Вот выдержка из документации, подтверждающей это:

6.10.1 Сравнение значений

Число встроенных числовых типов (Числовые типы - int, float, complex) и стандартных типов библиотек фракций. Fraction и decimal. Decimal можно сравнивать внутри и между их типами, с ограничением на то, что комплексные числа не поддерживают сравнение порядков.

Другими словами,мы хотим, чтобы разные числовые типы с одинаковыми значениями были равны.

PEP 20

Особые случаи не достаточно особенные, чтобы нарушать правила.

Хотя практичность превосходит чистоту.

Какая выгода в том, чтобы делать числовые типы несопоставимыми, помимо усложнения жизни в большинстве распространенных случаев?

0 голосов
/ 28 сентября 2018

Объекты разных типов, , кроме разных числовых типов, никогда не сравниваются одинаково.

И:

Python полностью поддерживает смешанную арифметику: когда бинарный арифметический оператор имеет операнды различных числовых типов, операнд с «более узким» типом расширяется до этогодругой, где целое число уже, чем с плавающей точкой, которая уже, чем сложная. Сравнения между числами смешанного типа используют одно и то же правило.

https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex

Логика сравнения реализована для каждого типа __eq__ метод .И стандартные числовые типы реализованы таким образом, что они поддерживают сравнения (и арифметические операции) между собой.Python как язык никогда не выполняет неявное преобразование типов (например, оператор == в Javascript будет выполнять неявное жонглирование типов).

0 голосов
/ 28 сентября 2018
== 

является оператором сравнения

Вы фактически спрашиваете переводчика, равны ли обе стороны вашего выражения.

Другими словами, вы просите его вернутьЛогическое значение, не для преобразования типов данных.Если вы хотите преобразовать типы данных, вам придется делать это неявно в своем коде.

0 голосов
/ 28 сентября 2018

10 == 10.0 переводится как (10).__eq__(10.0) (или даже более формально int.__eq__(10, 10.0)).Реализация int.__eq__ может обрабатывать сравнения с другими типами, но на уровне языка преобразование типов не выполняется.

...