Отрицательный ноль в python

[Python 3.1]

Я столкнулся с отрицательным нолем в выводе из python; он создается, например, следующим образом:

k = 0.0
print(-k)

Выход будет -0.0.

Однако, когда я сравниваю -k с 0.0 для равенства, он дает True. Есть ли разница между 0.0 и -0.0 (мне все равно, что у них, по-видимому, есть другое внутреннее представление, я только забочусь о их поведении в программе.) Есть ли скрытые ловушки, о которых я должен знать?

Ответ 1

Отъезд: - 0 (число) в Википедии

В основном IEEE фактически определяет отрицательный нуль

И этим определением для всех целей:

-0.0 == +0.0 == 0

Я согласен с aaronasterling, что -0.0 и +0.0 - разные объекты. Составляя их равными (оператор равенства), убедитесь, что в коде не введены тонкие ошибки. Подумайте о * b == c * d

>>> a = 3.4
>>> b =4.4
>>> c = -0.0
>>> d = +0.0
>>> a*c
-0.0
>>> b*d
0.0
>>> a*c == b*d
True
>>> 

[Изменить: больше информации на основе комментариев]

Когда я сказал для всех практических целей, я выбрал это слово довольно поспешно. Я имел в виду стандартное сравнение равенства.

Я добавил бы дополнительную информацию и ссылки в этом отношении:

(1) Как указано в ссылке, стандарт IEEE определяет сравнение, так что +0 = -0, а не -0 < +0. Хотя всегда можно было бы игнорировать знак нуля, стандарт IEEE этого не делает. Когда умножение или деление связано с нулевым знаком, обычные правила знака применяются при вычислении знака ответа.

Такие действия, как divmod, atan2, демонстрируют такое поведение. Фактически, atan2 соответствует определению IEEE, а также базовому "C" lib. См. Ссылку №2 для определения.

>>> divmod(-0.0,100)
(-0.0, 0.0)
>>> divmod(+0.0,100)
(0.0, 0.0)

>>> math.atan2(0.0, 0.0) == math.atan2(-0.0, 0.0)
True 
>>> math.atan2(0.0, -0.0) == math.atan2(-0.0, -0.0)
False

Один из способов - выяснить документацию, если реализация соответствует поведению IEEE. Из обсуждения также видно, что существуют и тонкие вариации платформы.

Как бы то ни было, этот аспект (соответствие требованиям IEEE) не соблюдается. См. Отказ от PEP 754 (№ 3) из-за незаинтересованности! Я не уверен, что это было подобрано позже.

ссылки:

Ответ 2

Это влияет на функцию atan2() (по крайней мере, в некоторых реализациях). В моем Python 3.1 и 3.2 в Windows (который основан на базовой реализации C, в соответствии с примечанием детализации реализации CPython рядом с bottom документации модуля Python math):

>>> import math
>>> math.atan2(0.0, 0.0)
0.0
>>> math.atan2(-0.0, 0.0)
-0.0
>>> math.atan2(0.0, -0.0)
3.141592653589793
>>> math.atan2(-0.0, -0.0)
-3.141592653589793

Ответ 3

Да, разница между 0.0 и -0.0 (хотя Python не позволит мне воспроизвести ее: -P). Если вы разделите положительное число на 0.0, вы получите положительную бесконечность; если вы разделите это же число на -0.0, вы получите отрицательную бесконечность.

Кроме того, между этими двумя значениями нет практической разницы.

Ответ 4

math.copysign() обрабатывает -0.0 и +0.0 иначе, если вы не используете Python на странной платформе:

math. copysign (x, y)
Возвращаем x со знаком y. На платформе, поддерживающей подписанные нули, copysign(1.0, -0.0) возвращает -1.0.

>>> import math
>>> math.copysign(1, -0.0)
-1.0
>>> math.copysign(1, 0.0)
1.0