我在python的输出中遇到负零;它的创建举例如下:
k = 0.0
print(-k)
输出为-0.0
。
但是,当我将-k
与0.0进行相等性比较时,它会产生True。 0.0
和-0.0
之间是否有任何区别(我不在乎他们可能有不同的内部表示;我只关心他们在程序中的行为。)是否有任何隐藏的陷阱我应该知道的?
答案 0 :(得分:29)
基本上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
>>>
[编辑:基于评论的更多信息]
当我为了所有实际目的说话时,我选择了这个词而不是草率。我的意思是标准的平等比较。
我会在这方面添加更多信息和参考资料:
(1)如参考文献所述,IEEE标准定义了比较,使得+ 0 = -0,而不是-0 <0。 + 0。尽管总是可以忽略零符号,但IEEE标准并未这样做。当乘法或除法涉及有符号零时,通常的符号规则适用于计算答案的符号。
像divmod,atan2这样的操作表现出这种行为。事实上,atan2与基础“C”lib一样符合IEEE定义。参见参考文献#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)的拒绝!我不确定这是否会被提起。
参考:
答案 1 :(得分:15)
它使atan2()
函数有所不同(至少在某些实现中)。在我的Windows上的Python 3.1和3.2中(基于底层的C实现,根据bottom of the Python math
module documentation附近的 CPython实现细节):
>>> 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
答案 2 :(得分:13)
math.copysign()
会以不同的方式对待-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
答案 3 :(得分:11)
是的,0.0和-0.0之间存在差异(尽管Python不允许我重现它:-P)。如果将正数除以0.0,则得到正无穷大;如果将相同的数字除以-0.0,则得到负无穷大。
除此之外,这两个值之间没有实际差异。
答案 4 :(得分: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