提问人:max 提问时间:11/3/2010 最后编辑:wjandreamax 更新时间:11/10/2022 访问量:49215
Python 中的负零
negative zero in python
问:
我在 python 的输出中遇到了负零;例如,它的创建方式如下:
k = 0.0
print(-k)
输出将为 。-0.0
但是,当我将相等性与 0.0 进行比较时,它会产生 True。和之间有什么区别吗(我不在乎它们可能有不同的内部表示;我只关心他们在程序中的行为。有什么隐藏的陷阱是我应该注意的吗?-k
0.0
-0.0
答:
是的,0.0 和 -0.0 之间是有区别的(尽管 Python 不允许我重现它:-P)。如果将正数除以 0.0,则得到正无穷大;如果将相同的数字除以 -0.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标准定义了比较,因此,而不是.尽管可以始终忽略零符号,但IEEE标准不会这样做。当乘法或除法涉及有符号的零时,通常的符号规则适用于计算答案的符号。+0 = -0
-0 < +0
操作喜欢并表现出此行为。事实上,它符合IEEE的定义,底层的“C”库也是如此。divmod
atan2
atan2
>>> 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 因不感兴趣而被拒绝!我不确定这是否是后来发现的。
评论
atan2
它在 atan2()
函数中有所作为(至少在某些实现中是这样)。在 Windows 上的 Python 3.1 和 3.2 中(根据Python math
模块文档底部附近的注释 CPython 实现详细信息,它基于底层 C 实现):
>>> 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
相同的值,但不同的数字
>>> 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
math.copysign()
以不同的方式处理,除非您在奇怪的平台上运行 Python:-0.0
+0.0
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
评论
为了概括或总结其他答案,实践中的差异似乎来自计算在 0 处停止的函数,其中不连续性来自 0 除法。然而,python 将 0 除法定义为错误。因此,如果使用 python 运算符计算任何内容,您可以简单地 将 -0.0 视为 +0.0,无需担心。相反,如果函数是由内置函数或用另一种语言(如 C)编写的库计算的,则 0 除法可以在该语言中以其他方式定义,并且可能会给出 -0.0 和 0.0 的不同答案。
如果您担心遇到 -0.0 的情况,只需添加 + 0。到等式。它不会影响结果,但会强制零为正浮点数。
import math
math.atan2(-0.0, 0.0)
Out[2]: -0.0
math.atan2(-0.0, 0.0) + 0.
Out[3]: 0.0
评论