Java 检查双重身份是否安全?

Java 检查双重身份是否安全?,java,floating-point,Java,Floating Point,我有以下代码: double x = 0; { ...do stuff ...} if(x == 0){ } 我一直被教导,你不应该检查浮点数是否相等。检查它是否等于零有什么不同吗?不应该检查浮点数是否相等的原因是浮点数不是完全精确的——有些数字在存储中存在不精确性,例如那些延伸到尾数太远的数字和重复的小数(请注意,我说的是基数2中的重复小数)。您可以将这种不精确性视为“向下舍入”。超出浮点数精度的数字会被截断,实际上是向下舍入 如果它没有改变,它将保持相等。但是,如果你稍微改变它,你可

我有以下代码:

double x = 0;

{ ...do stuff ...}

if(x == 0){

}

我一直被教导,你不应该检查浮点数是否相等。检查它是否等于零有什么不同吗?

不应该检查浮点数是否相等的原因是浮点数不是完全精确的——有些数字在存储中存在不精确性,例如那些延伸到尾数太远的数字和重复的小数(请注意,我说的是基数2中的重复小数)。您可以将这种不精确性视为“向下舍入”。超出浮点数精度的数字会被截断,实际上是向下舍入

如果它没有改变,它将保持相等。但是,如果你稍微改变它,你可能不应该使用相等,而应该使用像
(x<0.0001&&x>-.0001)
这样的范围


简而言之:只要你不是在一个很小的级别上玩x,就可以了。

如果你试图捕捉的0是初始化时设置的原始0,这是安全的。但是,如果你期望数学运算得到一个0,这是不安全的。

你仍然不应该检查它是否等于零。只要检查它是否接近零就可以了。

private final static double EPSILON = 0.00001;
if (x + EPSILON > 0 && x - EPSILON < 0){
...
}
private final static double EPSILON=0.00001;
如果(x+ε>0&&x-ε<0){
...
}

如果您自己设置它,并希望查看它是否发生过更改,您可以安全地检查是否相等(如使用sentinel值),尽管NaN在这方面更安全

float x=Float.NaN;
{
   //some code that may or may not set x
}
if(Float.isNaN(x))//it never got set

double有正零和负零。
==
在正零和负零之间返回false。另外,
=
在两个nan之间返回false。

我不明白,如果你将x初始化为0,为什么检查0是否是一个有效值不好?当你开始达到li时,0是一个双浮点数的大量舍入值mits。同样的原因,如果你有3位数字以10为基数,你有.004,除以3,你期望.001,但谁知道会发生什么。托马斯的修正:从技术上讲,这不是四舍五入,而是由于精度有限和浮点数的二进制性质而导致的不准确。有人应该总结一下这个问题的所有答案。这不是四舍五入事情是这样的,但由于浮点数的表示,无法存储某些数字。0可以用浮点数精确表示,但并非所有值都可以。例如,0.1必须近似。@Thomas Rounding down.
3/2
的原因与
1
相同,不是舍入。IEEE flo中的不精确性点表示法。与舍入完全无关。同样的@Thomas。你会说
3/2
1
,因为“整数表示法不精确”?参见第173页,或者是的,它与舍入完全无关。除了它是(甚至由@Thomas链接)。您不应使用绝对值,而应使用相对值。例如,
if(value>=target*(1-ε)&&value@HovercraftFullOfEels这仅在目标为正时有效。当您想从数学运算中比较0时,正确的方法应该是什么?您错了。负零比较等于正零。这是Java遵循的IEEE-794标准所要求的。