我有以下的代码:
double x = 0;
{ ...do stuff ...}
if(x == 0){
}
我一直被教导不应该检查浮点数是否相等。但是检查它是否等于零有所不同吗?
我有以下的代码:
double x = 0;
{ ...do stuff ...}
if(x == 0){
}
我一直被教导不应该检查浮点数是否相等。但是检查它是否等于零有所不同吗?
不能使用等号判断浮点数是否相等的原因是浮点数不是完全精确的。有一些数字在存储时存在一定的不准确性,例如那些延伸到尾数和循环小数的数字(请注意,我说的是二进制下的循环小数)。你可以将这种不准确性看作是“向下取整”。超出浮点数精度的数字位被截断,实际上是进行了向下取整。
如果浮点数没有变化,它们之间的等式就会成立。但是,如果你稍微改变一下它们,你可能就不应该使用等式,而是使用类似于(x < 0.0001 && x > -0.0001)
这样的范围。
简而言之:只要你不在一个非常小的水平上操作x,就没问题。
3/2
等于1
的原因相同。 - Ryan Amos3/2
是 1
,是因为“整数表示中的不精确性”吗?请参阅《计算机科学家应该了解的浮点运算》第173页或维基百科中的可表示数字、转换和舍入。 - Museful如果你试图捕获的0是在初始化时设置的原始0,那么是安全的。但是,如果你期望从数学运算中得到一个0,则不安全。
你仍然不应该检查它是否等于零,只需要检查它是否接近于零。
private final static double EPSILON = 0.00001;
if (x + EPSILON > 0 && x - EPSILON < 0){
...
}
if (value >= target * (1 - epsilon) && value <= target * (1 + epsilon ))
。特别是当值可以在大范围内变化时更应如此。 - Hovercraft Full Of Eels如果您自己设置它并希望查看其是否更改,可以安全地检查是否相等(例如使用哨兵值),但对于此类情况,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。