Java中的0.0和-0.0(IEEE 754)

Java中的0.0和-0.0(IEEE 754),java,floating-point,ieee-754,Java,Floating Point,Ieee 754,Java与IEEE 754完全兼容,对吗?但是我对java如何决定浮点加法和减法的符号感到困惑 这是我的测试结果: double a = -1.5; double b = 0.0; double c = -0.0; System.out.println(b * a); //-0.0 System.out.println(c * a); //0.0 System.out.println(b + b); //0.0 System.out.println(c + b); //0.0 Syste

Java与IEEE 754完全兼容,对吗?但是我对java如何决定浮点加法和减法的符号感到困惑

这是我的测试结果:

double a = -1.5;
double b = 0.0;
double c = -0.0;
System.out.println(b * a);  //-0.0
System.out.println(c * a);  //0.0
System.out.println(b + b);  //0.0
System.out.println(c + b);  //0.0
System.out.println(b + c);  //0.0
System.out.println(b - c);  //0.0
System.out.println(c - b);  //-0.0
System.out.println(c + c);  //-0.0
我认为在乘法和除法中,符号是这样决定的:符号(a)或异或符号(b), 但是我想知道为什么0.0+-0.0=0.0,Java是如何决定加号和减号的?IEEE 754中有描述吗

我还发现Java可以在某种程度上区分0.0和-0.0之间的相似性,因为

System.out.println(c == b);    //true
System.out.println(b == c);    //true
java中的“==”是如何工作的? 是否将其视为特殊情况?

IEEE754指定有符号零。也就是说,-0.0和+0.0分别表示

它们被定义为在平等性上比较真实


Java正确地实现了这一点。

这里没有特定于Java的内容,而是由IEEE754指定的

发件人:

根据IEEE 754标准,负零和正零 应与通常的(数值)比较相同 运算符,如C和Java的==运算符

因此,以下数字比较相等:

(+0) - (-0) == +0

在所有现代语言中,当处理原始浮点数时,您都会得到相同的行为。

我会在其他答案中添加一条,您可以通过检查
1.0/myzero>0.0
或检查数字是否为按位零,如
Double.doubletoongbitz(myzero)!=0
(对
-0
为真,对
+0
为假)

维基百科上有一些有趣的观察结果

在Java中,要区分IEEE 754正零和IEEE 754负零,可以使用双包装器

System.out.println((0.0==-0.0)); // prints out TRUE (as expected)
System.out.println(new Double(0.0).
         equals(new Double(-0.0))); // prints out FALSE

另外,
java.lang.Math.min(-0.0,+0.0)
的计算结果为
-0.0
,而
java.lang.Math.max(-0.0,+0.0)
的计算结果为
+0.0

在我看来,你问过“java如何决定加减符号”,到目前为止还没有回答

IEEE754似乎并没有完全定义结果:它只是说:

[…]和或差x的符号− y被认为是一个总数 x+(−y) ,最多与一个加数符号不同;[...] 即使操作数或结果为零或无穷大,这些规则也应适用

(§6.3;文本在修订之间保持不变。)我理解这意味着
b-c
+0。
c+c
c-b
-0。
,但
b+c
c+b
(和
b-b
,和
c-c
)可以是
+0。

[编辑部分]

然后IEEE754补充道:

当符号相反的两个操作数之和(或符号相同的两个操作数之差)正好为零时,在除向外的所有舍入模式中,该和(或差)的符号应为+─∞ [……]

这在这里也应该适用;并且它将表达式
b+c
c+b
b-b
c-c
的符号限制为
+0。
(因为舍入模式从不朝前)─∞ (用Java语言)

很抱歉,我错过了第一次阅读的那部分。事实上,它似乎完全由IEEE 754标准规定

[版本结束]

另一方面,Java规范()更精确,并且

[…]符号相反的两个零之和为正零

Javascript()具有类似的规范:

[…]两个大小相同、符号相反的非零有限值之和为
+0


0.0==-0.0不是Java的特殊性:它是由IEEE754指定的。如果您想详细说明,请参阅IEEE 754的第6.3节:“当两个符号相反的操作数之和(或两个符号相同的操作数之差)正好为零时,该和(或差)的符号在所有舍入方向属性中应为+0,但舍入方向为负值除外;在该属性下,精确零和(或差)的符号应为-0。”这是一个很好的答案。你对
+0++0=+0
的解释并没有直接回答OP的第一个问题,他们写了
+0+-0=+0
(不是负号)。(我猜
(+0)+-0=(+0)-(+0)=(+0)=(+0)
,而
(-0)+(-0)=(-0)=(-0)
,但因为
(+0)=(-0)
这两个和是相等的,因此保留了交换性。)@chiccodoro为了更清晰,我截断了引用的伪码的第一部分。对不起,我想你弄错了。你的方程式是对+0++0的有益解释,但不是对+0+-0(将负零添加到正零)的有益解释。截断后,情况仍然如此。@chiccodoro:我试图回答缺少的一点: