使用float进行比较问题处理

float compare

Abstract

使用float数据进行精确计算和比较,可能由于精度问题导致程序逻辑异常。

Explanation

使用float数据进行比较,计算机表达double和float型数据其实是个近似值,而不是精确值,直接用
它们进行比较判断,得到的结果可能与预期完全不同,导致程序逻辑异常。最严重的情况是进行相等
性比较"=="和"!=",极易错误;其次是">=""<="等比较判断,也比较容易出错。
示例1 double型数据进行判断。
public static double integral(MyFunction f, double x1, double x2) {
   double x = x1;
   double result = 0;
   double step = (x2 - x1) / 700;
   while (x != x2) {
     // 可以改为 (x ﹤= x2)
     result = result + f.valueFor(x) * step;
     x = x + step;
   }
   return result;
}
上述代码可能导致无限的循环,因为由于计算的误差,x!=x2,可能永远是成立的。
 
示例2 double型数据进行判断。
public static final double MAX_MONEY=0.2public string test(double d1,double d2){
   double d3=d1+d2;//
   if(d3<=MAX_MONEY){
     return "OK";
   }
}
上述代码,当d1=d2=0.1时,d3=0.20000000149011612是>0.2的,程序员想当然以为d3<=MAX_MONEY是
成立的,进行了错误的处理逻辑。
 

Recommendation(解决办法)

1、进行大于或等于、小于或等于,或小于某值的不同绝对值的检查,例如 Math.abs(x1-x2) ﹤MIN_DIFF;
bool float_equals(float a,float b){
   if (abs(a-b)<=1e-6)
     return true;
   return false;
}
2、根据场景可以考虑采用整数类型或用于精确表达小数的BigDecimal类型替代。
posted @ 2021-05-13 15:51  Shinoburedo  阅读(612)  评论(0编辑  收藏  举报