58

我在 python 的输出中遇到负零;它的创建例如如下:

k = 0.0
print(-k)

输出将是-0.0.

但是,当我比较-k0.0 是否相等时,它会产生 True。0.0和之间有什么区别-0.0(我不在乎它们可能具有不同的内部表示;我只关心它们在程序中的行为。)是否有任何我应该注意的隐藏陷阱?

4

6 回答 6

43

在 Wikipedia 中查看-0(数字)

基本上 IEEE 实际上确实定义了一个负零。

根据这个定义,出于所有目的:

-0.0 == +0.0 == 0

我同意aaronasterling的观点,-0.0并且+0.0是不同的对象。使它们相等(相等运算符)可确保代码中不会引入细微的错误。
考虑到a * 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
>>> 

[编辑:基于评论的更多信息]

当我出于所有实际目的说这个词时,我是相当仓促地选择了这个词。我的意思是标准的平等比较。

正如参考资料所说,IEEE 标准定义了比较,因此+0 = -0,而不是-0 < +0。尽管总是可以忽略零的符号,但 IEEE 标准并没有这样做。当乘法或除法涉及带符号的零时,通常的符号规则适用于计算答案的符号。

操作喜欢divmodatan2表现出这种行为。事实上,它与底层的“C”库一样atan2 符合IEEE 定义。

>>> 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因不感兴趣而被拒绝!我不确定这是不是后来捡到的。

另请参阅每个计算机科学家应该了解的关于浮点运算的知识

于 2010-11-03T01:04:11.380 回答
20

math.copysign()对待-0.0+0.0不同,除非你在一个奇怪的平台上运行 Python:

math.copysign ( x , y )
     返回带有y符号的x。在支持有符号零的平台上,返回.copysign(1.0, -0.0)-1.0

>>> import math
>>> math.copysign(1, -0.0)
-1.0
>>> math.copysign(1, 0.0)
1.0
于 2014-08-16T08:12:00.010 回答
17

它在atan2()功能上有所不同(至少在某些实现中)。在我在 Windows 上的 Python 3.1 和 3.2 中(根据 Python模块文档底部附近的注释CPython implementation detail,它基于底层 C 实现):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
于 2010-11-03T04:24:20.040 回答
14

是的,0.0 和 -0.0 之间是有区别的(尽管 Python 不会让我重现它:-P)。如果将正数除以 0.0,则得到正无穷大;如果将相同的数字除以 -0.0,则会得到负无穷大。

但是,除此之外,这两个值之间没有实际差异。

于 2010-11-03T01:01:53.187 回答
1

相同的值,但不同的数字

>>> Decimal('0').compare(Decimal('-0'))        # Compare value
Decimal('0')                                   # Represents equality

>>> Decimal('0').compare_total(Decimal('-0'))  # Compare using abstract representation
Decimal('1')                                   # Represents a > b

参考: http:
//docs.python.org/2/library/decimal.html#decimal.Decimal.compare http://docs.python.org/2/library/decimal.html#decimal.Decimal.compare_total

于 2014-03-14T06:55:33.290 回答
0

为了概括或总结其他答案,实践中的差异似乎来自计算在 0 处中断的函数,其中不连续性来自 0 除法。然而,python 将 0 除法定义为错误。因此,如果使用 python 运算符计算任何内容,您可以简单地将 -0.0 视为 +0.0,无需担心。相反,如果函数是由内置函数或用另一种语言(如 C)编写的库计算的,则 0 除法可能会在该语言中以其他方式定义,并且可能对 -0.0 和 0.0 给出不同的答案。

于 2021-11-13T16:21:18.473 回答