为什么浮点数已经签名为零?
为什么双打有-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在这种语义上是相同的一个模式,所以即使还有两个编码,也只会有一个零)。