为什么我们在Ruby中有0.0和-0.0?

Bru*_*cho 69 ruby floating-point negative-zero

在ruby中,为什么我可以给负0.0浮点数分配一个负号,此功能有任何用处吗?有人可以向我解释这个吗?

-0.0
#=> -0.0

-0.0 * -1
#=> 0.0
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 101

您可以在Ruby中为0.0浮点数分配一个负号,因为所有IEEE 754浮点数都有一个符号位来指示该数字是正数还是负数。

下面是二进制表示2.5-2.5

[2.5].pack('f').unpack1('b*')
#=> "00000000000000000000010000000010"

[-2.5].pack('f').unpack1('b*')
#=> "00000000000000000000010000000011"
Run Code Online (Sandbox Code Playgroud)

最后一位是符号位。注意,所有其他位都相同。

另一方面,零为零0

['00000000000000000000000000000000'].pack('b*').unpack1('f')
#=> 0.0
Run Code Online (Sandbox Code Playgroud)

和零,符号位为1

['00000000000000000000000000000001'].pack('b*').unpack1('f')
#=> -0.0
Run Code Online (Sandbox Code Playgroud)

尽管0.0-0.0在数值上相等,但是它们在对象级别上并不相同:

(0.0).eql?(-0.0)   #=> true
(0.0).equal?(-0.0) #=> false
Run Code Online (Sandbox Code Playgroud)

负零有一些特殊的性质。例如:

1 / 0.0    #=> Infinity
1 / -0.0   #=> -Infinity
Run Code Online (Sandbox Code Playgroud)

-显式分配不是获得的唯一方法-0.0。您可能还会得到-0.0基本算术运算的结果:

-1.0 * 0 #=> -0.0
Run Code Online (Sandbox Code Playgroud)

  • @Bakuriu,“注释”是古英语,表示“不是”。(自白:我的意思是写“不要惊讶”。打扰一下。) (16认同)
  • @Crowley IEEE-754特别指出“ squareRoot **(-0)应该为-0。” (12认同)
  • @CarySwoveland`(-0.0)*(-0.0)=> + 0.0`令人惊讶吗?它完全遵循符号规则,就像在“ 1 / -0.0 = -inf”等情况下一样。奇怪的是`sqrt(-0.0)= -0.0`,因为大多数人只期望平方根的值> = 0 ... (8认同)
  • @Bakuriu从技术上讲它们是正确的,因为IEEE 754中的-0.0> = 0.0 (7认同)
  • @Bakuriu的sqrt(-0.0)=> 0 + 0i不是正确的结果吗,复数为零? (4认同)
  • @CJDennis:即使是不同的值,根据IEEE754,`0.0`也会等于-0.0。如这个答案所示,Ruby具有数字比较,可以找到相等的值,还有对象表示或可以比较出差异的比较。在大多数语言(如C / C ++)中,标准比较运算符会发现它们相等。在x86汇编中,比较和发现它们不相等的唯一方法是使用按位整数比较(根本不是浮点,并且可以找到彼此相等的NaN值而不是无序的)。 (4认同)
  • @Crowley甚至在实际的数学运算中(不是IEEE754),“复数零”仍然只是零。 (4认同)
  • 另请参见[零号签名]的Wiki(https://en.wikipedia.org/wiki/Signed_zero#Properties_and_handling)。令人惊讶地注意`(((-0.0)*(-0.0)#=> 0.0`))。原来,这个问题比我最初想的要有趣。 (2认同)
  • @ Yakk-AdamNevraumont 0是真实的,对于除统计学家之外的所有其他人而言,0 == 0。浮点数==浮点数是无意义的,因为浮点数的存储和呈现方式从根本上是不同的,这是有损的。浮点数是1和0。直到最后一位,它们可以相等。但是他们如何获得这种方式是根本不同的数学。 (2认同)

hob*_*bbs 41

数学运算具有实数结果,但是我们将那些实数结果映射到最接近的浮点数,这称为“舍入”。对于每一个浮点数,有一个范围,将舍入到浮球实数,有时想到浮动的,与该范围内的实数被认定是非常有用的。

由于浮点数是有限的,因此必须有最小的正浮点数,而相反的是最小(幅值)负浮点数。但是,甚至小于那些的实数结果会怎样?好吧,它们必须“四舍五入”。但是“一个很小的数字大于零”和“一个很小的数字小于零”是完全不同的事物,它们的数学行为也有很大不同,所以为什么要舍入,而又要舍弃它们之间的区别呢?我们没有必要。

因此,浮点数0不仅包含实数0,而且还包含太小而无法表示的数。浮点数-0太小而无法表示负数。当您在算术中使用它们时,它们遵循诸如“负数乘以正数等于负数;负数乘以负数等于正数”之类的规则。即使在舍入过程中我们几乎忘记了这些数字的所有内容,我们仍然没有忘记它们的符号。

  • @CarySwoveland只会给其他人造成同样大小的烦恼(但符号相反):) (15认同)

mrz*_*asa 26

它不是Ruby的功能,而是浮点数规范的一部分。看到这个答案。负零等于正零:

-0.0 == 0.0
# => true
Run Code Online (Sandbox Code Playgroud)