DX之浮点数比较

我们都知道在C++数与数的比较我们都知道用==,!==等等方法,但在浮点数比较中刚可有行用这种,

首先,浮点数在计算机当中是以二进制的方式表达的,所以无法表达其精度,其次计算机浮点数的精度float类型下,只有七位,在进行浮点运算的时候,这个精度往往会导致运算的结果和实际期望的结果之间有误差。。。

这样我们会自然而然想到fabs(a-b)>epsilon这个方法,但它也不稳妥,首先,epslion是一个绝对的数据,也就是误差分析当中说说的绝对误差,、

既然绝对误差不可以,那么自然的我们就会想到了相对误差

bool IsEqual(float a, float b, float relError ) {

        return ( fabs ( (a-b)/a ) < relError ) ? true : false;

}

这样写还不完善,因为是拿固定的第一个参数做比较的,那么在调用 IsEqual(a, b, relError ) 和 IsEqual(b, a, relError ) 的时候,可能得到不同的结果 同时如果第一个参数是0的话,就有可能是除0溢出 这个可以改造 把除数选取为a和b当中绝对数值较大的即可

bool IsEqual(float a, float b, relError ) {

       if (fabs(a)<fabs(b)) return  ( fabs((a-b)/a) > relError ) ? true : false;

       return  (fabs( (a-b)/b) > relError ) ? true : false;

 };

在某些特殊情况下, 相对误差也不能代表全部 比如在判断空间三点是否共线的时候,使用判断点到另外两个点形成的线段的距离的方法的时候 只用相对误差是不够的,应为线段距离可能很段,也可能很长,点到线段的距离,以及线段的长度做综合比较的时候,需要相对误差和绝对误差结合的方式才可以 相对完整的比较算法应该如下:

 bool IsEqual(float a, float b, float absError, float relError ) {  

        if (a==b) return true;

        if (fabs(a-b)<absError ) return true;

         if (fabs(a>b) return  (fabs((a-b)/a>relError ) ? true : false;

        return  (fabs((a-b)/b>relError ) ? true : false;

}

这样才相对完整

posted on 2011-10-26 21:22  咆哮的蛋蛋  阅读(220)  评论(0编辑  收藏  举报