浮点数比较大小
来源:互联网 发布:统计学df知乎 编辑:程序博客网 时间:2024/04/29 16:31
在数学运算当中经常会涉及到判断两个数是否相等的情况
对于整数很好处理 A==B这样的一个语句就可以解决全部的问题
但是对于浮点数是不同的
首先,浮点数在计算机当中的二进制表达方式就决定了大多数浮点数都是无法精确的表达的
现在的计算机大部分都是数字 计算机,不是模拟机,数字机的离散化的数据表示方法自然无法精确表达大部分的数据量的。
其次计算机浮点数的精度在单精度float类型下,只有7位,在进行浮点运算的时候,这个精度往往会导致运算的结果和实际期望的结果之间有误差
因为前两个原因,我们很难用 A==B来判定两个浮点数是否相同
很自然,我们可以想到 fabs(A-B) < epsilon 这样的一种判别方法
但是这种判别方法稳妥吗?
它也不稳妥。
首先, epsilon是一个绝对的数据,也就是误差分析当中说说的绝对误差
使用一个固定的数值,对于float类型可以表达的整个数域来说是不可以的
比如epsilon取值为0.0001,而a和b的数值大小也是0.0001附近的,那么显然不合适
另外对于a和b大小是10000这样的数据的时候,它也不合适,因为10000和10001也可以认为是相等的呢
适合它的情况只是a或者b在1或者0附近的时候
既然绝对误差不可以,那么自然的我们就会想到了相对误差
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 )
{
对于整数很好处理 A==B这样的一个语句就可以解决全部的问题
但是对于浮点数是不同的
首先,浮点数在计算机当中的二进制表达方式就决定了大多数浮点数都是无法精确的表达的
现在的计算机大部分都是
其次计算机浮点数的精度在单精度float类型下,只有7位,在进行浮点运算的时候,这个精度往往会导致运算的结果和实际期望的结果之间有误差
因为前两个原因,我们很难用 A==B来判定两个浮点数是否相同
很自然,我们可以想到 fabs(A-B) < epsilon 这样的一种判别方法
但是这种判别方法稳妥吗?
它也不稳妥。
首先, epsilon是一个绝对的数据,也就是误差分析当中说说的绝对误差
使用一个固定的数值,对于float类型可以表达的整个数域来说是不可以的
比如epsilon取值为0.0001,而a和b的数值大小也是0.0001附近的,那么显然不合适
另外对于a和b大小是10000这样的数据的时候,它也不合适,因为10000和10001也可以认为是相等的呢
适合它的情况只是a或者b在1或者0附近的时候
既然绝对误差不可以,那么自然的我们就会想到了相对误差
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;
}
这样才相对完整
参照MSDN定义:
/* Compile options needed: none. Value of c is printed with a decimalpoint precision of 10 and 6 (printf rounded value by default) toshow the difference*/#include // Define your own tolerance
const double EPSILON = 1.00e-07;
const float FLT_EPSILON = 1.192092896e-07F;
const double DBL_EPSILON = 2.2204460492503131e-016;
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))int main(){float a, b, c;a = 1.345f;b = 1.123f;c = a + b;// if (FLOAT_EQ(c, 2.468)) // Remove comment for correct resultif (c == 2.468) // Comment this line for correct resultprintf("They are equal.\n");elseprintf("They are not equal! The value of c is %13.10f,or %f",c,c);}
- 浮点数比较大小
- 浮点数比较大小
- 浮点数比较大小
- 浮点数比较大小
- 浮点数比较大小
- 浮点数的大小比较
- 浮点数的大小比较
- 浮点数的大小比较
- PHP浮点数比较大小
- 两个浮点数比较大小方法
- C语言浮点数比较大小
- 两个浮点数比较大小方法
- C语言浮点数比较大小
- 浮点数的大小比较问题
- C++ 之 浮点数的大小比较
- 浮点数比较大小的问题
- 比较两个浮点数的大小
- 浮点数比较大小的问题
- go语言示例(总目录)
- 大数据应用之个性化推荐的十大挑战
- HBase缓存的使用
- 参加OpenMap的感受
- 电话拨号器
- 浮点数比较大小
- 嘀嗒APP打车体验记
- PKU1574&&DFS
- HDFS APPEND性能测试
- go语言示例:hello world
- js,jquery字符串转换json,兼容各种浏览器
- jquery使用列表标签实现的可拖拽listbox
- HDU 4772 Zhuge Liang's Password
- 博客开通啦