为什么浮点数已经签名为零?

为什么双打有-0+0 ? 什么是背景和意义?

-0 (一般)被视为0 *******。 当负的浮点数如此接近于零以致它可以被认为是0 (清楚地说,我指的是算术下溢 ,并且以下计算的结果被解释为正好是 ±0 ,而不是只是非常小的数字)。 例如

 System.out.println(-1 / Float.POSITIVE_INFINITY); 
 -0.0

如果我们考虑与数相同的情况,我们将收到我们的好老0

 System.out.println(1 / Float.POSITIVE_INFINITY); 
 0.0

*******这是一个使用-0.0结果与使用0.0时不同的情况:

 System.out.println(1 / 0.0); System.out.println(1 / -0.0); 
无穷
 -无穷

如果我们考虑函数1 / x这是有道理的。 当x+接近0 ,我们应该得到无穷,但是当它接近于- ,我们应该得到无穷。 函数的图表应该明确这一点:

( 来源 )

用math术语来说:

在这里输入图像说明

在这里输入图像说明

这说明在计算意义上0-0之间的一个显着差异。


这里有一些相关资源,其中一些已经提出来了。 为了完整起见,我已经包括了它们:

  • 维基百科有关签署零的文章
  • “每个计算机科学家应该知道什么是浮点运算” (见签名零部分)
  • (PDF) “关于什么是符号位” ,这是W. Kahan的一篇有趣的论文。

从维基百科

带符号的零有符号。 在普通算术中, −0 = +0 = 0 。 在计算中,在一些数字表示中存在两个零的概念,通常用−0和'+0'表示,分别表示负零零正零

这发生在整数的符号和幅度以及1的补码有符号数表示中,并且出现在大多数浮点数表示中。 数字0通常编码为+0,但可以用+0或-0表示。

根据IEEE 754 standard ,负零和正零应与通常的(数值)比较运算符(如C和Java的==运算符) 相当 。 ( 来源 )。

当你有一个浮点运算产生的结果是一个负的浮点数 接近零 ,但不能被表示 (在计算)它产生一个“-0.0”。 例如 – 5.0 / Float.POSITIVE_INFINITY -> -0.0

这与-0.0+0.0区别在于给出的信息比简单地给出最终结果0更多。当然,这个概念“仅”存在于计算机中使用的有限表示系统中。 在math中,你可以表示任何数字,即使它非常接近零。

−0+0是导致下溢的操作的结果,类似的−00+00是导致溢出的操作的结果。 对于引起math不确定性的操作, NaN (例如0/0)。

-0.0和0.0有什么区别?

实际上,两者都表示0.此外,(-0.0 == 0.0)返回true 。 然而:

1) 1/-0.0产生-Infinity,1/0.0产生无穷大

2) 3 * (+0) = + 0+0/-3 = -0符号规则适用于对有符号零进行乘法或除法。

强制性阅读“ 每个计算机科学家应该了解的浮点算术 ”(在评论中build议)。

请参阅每个计算机科学家有关浮点算术应知的 “签名零”一节

Java中的零浮点和double不只是表示真正的零。 它们也被用作任何计算的结果,其精确结果的幅度太小,无法表示。 在许多情况下,负数下溢与正数下溢之间存在很大差异。 例如,如果x是一个非常小的正数, 1/x应该是正无穷大, 1/(-x)应该是负无穷大。 有符号零保留下溢结果的符号。

在Kahan的论文“ 复杂基本函数的分支切割,或者关于什么是符号位 ”(以及他关于这个主题的一些谈话)中,浮点有符号零的有用性的典型参考。

简短的说法是,在相当常见的工程应用中,通过签名零来保存的符号信息对于从数值方法中获得正确的解决scheme是必要的。 对于大多数实际操作来说,零的符号意义不大,但是当考虑复值函数或者使用保形映射时,零符号可能突然变得非常关键。

还值得注意的是,原来的(1985) IEEE-754委员会考虑并拒绝了支持浮点运算的投影模式,在这种模式下,只有一个无符号无穷大(+/- 0在这种语义上是相同的一个模式,所以即使还有两个编码,也只会有一个零)。