由于在二进制表示中存储这些值的挑战,浮点数学是不精确的。更糟糕的是,浮点数学不是关联的; 推动floatdouble通过一系列简单的数学运算,由于每个步骤发生的舍入,答案将根据这些操作的顺序而不同。

即使是简单的浮点赋值也不简单:

float f = 0.1; // 0.100000001490116119384765625 
double d = 0.1; // 0.1000000000000000055511151231257827021181583404541015625

(结果将根据编译器和编译器设置而有所不同);

因此,在值或值上使用equality(==)和inequality(!=)运算符几乎总是一个错误。相反,最好的方法是完全避免浮点比较。如果不可能,您应该考虑使用Java的浮点处理之一,例如可以正确处理浮点比较。第三种选择是不要考虑相等性,而是考虑价值是否足够接近。即,将存储值和期望值之间的差的绝对值与可接受误差的余量进行比较。请注意,这并不能掩盖所有的情况下(和 为实例)。floatdoubleNumbersBigDecimalNaNInfinity

此规则检查浮点数和双精度数的直接和间接相等/不等于测试的使用。

不合规的代码示例

float myNumber = 3.146; 
if(myNumber == 3.146f){//不合规。由于浮点不精确,这将是假的
  ... ... 
} 
if(myNumber!= 3.146f){//不合规。由于浮点不精确,这将是真的
  // ... 
} 

如果(myNumber <4 || myNumber> 4){//不合规; 间接不等式检验
  // ... 
} 

float zeroFloat = 0.0f; 
if(zeroFloat == 0){//不合规。计算可能最终得到一个接近但不等于零的值。
}

解决方法

两实数相等:两实数的差在允许的范围内认为相等既可认为是相等的。

范围:1e-6(0.000001)

主要代码:

boolean IsEqual(double a,double b)
{
    //计算机表示浮点数(float或double类型)都有一个精度限制,对于超出了精度限制的浮点数,计算机会把它们的精度之外的小数部分截断。因此,本来不相等的两个浮点数在计算机中可能就变成相等的了
//因此一般不会直接用“==”或者“!=”对两个浮点数进行比较。判断两个浮点数是否相等可以根据他们的差的绝对值是否大于0来进行判断。
//考虑到实际应用,一般如果两个浮点数之差的绝对值小于或等于某一个可接受的误差(即精度,比如0.00000001即可),就认为它们是相等的。
    return Math.abs(a-b) < 0.000001;
}