负零的绝对值 - bug,还是浮点标准的一部分?

Chr*_*lor 19 floating-point haskell

我知道带符号的零用于区分下溢与正数或负数,因此值得区分它们.直觉我觉得-0.0应该是绝对值0.0.但是,这不是Haskell所说的:

Prelude> abs (-0.0)
-0.0
Run Code Online (Sandbox Code Playgroud)

对于它的价值,Python 2.7不同意:

>>> -0.0
-0.0
>>> abs(-0.0)
0.0
Run Code Online (Sandbox Code Playgroud)

这是一个错误,还是标准的一部分?

Mar*_*son 12

您描述的行为肯定与IEEE 754标准不一致,后者在最近的版本中说:

ABS(x)的拷贝的浮点操作数x到在相同的格式的目的地,符号位设置为0(正).

这是在IEEE 754-2008的第5.5.1节中,标题为"符号位操作".虽然我无法提供标准本身的链接,但您可以在7.5.1节中的标准的最后一个公开草案中看到大致相同的语言.(一般来说,标准与草案有很大不同,但这一点几乎没有变化.)

除非Haskell明确声称遵循IEEE 754标准,否则这不会成为Haskell中的错误,而且声称absPrelude 中的实现应映射到IEEE 754 abs功能.该标准仅要求abs必须提供操作,但没有说明如何拼写.


ham*_*mar 7

这是Haskell报告中定义的行为.

6.4.4幅度和标志

数字具有幅度符号.功能abssignum适用于任何数字并满足法律:

abs x * signum x == x
Run Code Online (Sandbox Code Playgroud)

对于实数,这些函数定义如下:

abs x    | x >= 0  = x  
         | x <  0  = -x  

signum x | x >  0  = 1  
         | x == 0  = 0  
         | x <  0  = -1
Run Code Online (Sandbox Code Playgroud)

由于负零等于零-0.0 >= 0,所以是真的abs (-0.0) = -0.0.这也与定义一致signum,因为-0.0 * 0.0 = -0.0.

  • 很公平。但是,如果`abs (-0.0) == 0.0`,关系`abs x * signum x == x` 仍然成立,这对我来说似乎更直观(并避免了`a == b` 不暗示的奇怪情况当 `a` 和 `b` 是浮点值时,`fa == fb`。 (2认同)
  • 好的,我明白你的意思了。我想要使​​这一点保持一致,您需要有 `signum (-0.0) == -0.0` 和 `signum 0.0 == 0.0`,这确实使问题变得有些复杂。 (2认同)