浮点计算中的近似处理问题

在浮点计算中经常会遇到这样的情景:检查一个数值是否为另一个数值的整数倍。这个问题对于整数计算而言完全不是问题,但放到浮点数身上就存在误差导致的近似问题。

 

比如两个浮点数相除:d1 / d2 = 2.9981,那么 d1 是否是 d2 的整数倍呢?这取决于允许的误差精度,如果误差精度为 0.01 那么 d1 就可以近似为 d2 的3倍;但如果误差精度为 0.001 那么 d1 就不是 d2 的整数倍。

 

下面提供一个函数实现来完成上面的整数倍计算。

 

//
// 检查一个浮点数是否为另一个浮点数的整数倍,如果结果是 true,则将整数倍数保存在 mult 指针中;
// 如果 multi 指针为 NULL 则不返回倍数
//
// 参数说明
//   a        除数
//   b        被除数
//   prec     误差精度,比如:0.0001
//   mult     指向保存整数倍数的变量,可以为 NULL,如果不是整数倍则不改变该指针指向变量的值
//
// 返回值
//   a是否为b的整数倍
//
bool CheckDoubleMultiple(double a, double b, double prec, int *mult) {
  
// 先计算相除的结果
  double d = a / b;
  
  
// 给原始相除的结果加上误差精度值,如果 d 可以近似为整数倍,那么 m 的值就是该整数倍数
  double m = (double)((int)(d + prec));
  
  
// 要求相除结果在区间 [ m - 0.0001, m + 0.0001 ] 内,注意:m 是一个整数值!
  if ((d - prec) <= m &&  m <= (d + prec)) {
    
if ( mult ) *mult = static_cast<int>(m);
    
return true;
  } 
else {
    
return false;
  }
}

 

 

 

posted @ 2011-05-27 12:29  edwardlost  阅读(585)  评论(0编辑  收藏  举报