看下面一个例子:
int main()
{
double d1 = 1.0;
double d2 = 0.0;
for(int i = 0; i < 10; ++i)
d2 += 0.1;
if(d2 == d1)
cout << "==";
else
cout << "!=";
return 0;
}
很容易会认为输出是“==”,其实是“!=”。设置cout精度为20,输出d2,发现d2的值为0.999999…8。值并是1.0,所以上面的问题就很容易解释了。
要考虑到浮点数在计算机中是如何表示的。数据都是通过二进制来表示的。
任何一个整形毫无疑问都能通过一个足够多位数的二进制数来表示。但是一个小数不一定。一个小于0~1之间的数可以通过x1*0.5+x2*0.25+x3*0.125+...
来表示,但是不一定能精确表示,有舍入误差。所以才有了flaot和double等不同精度的类型,位数越多精度越高。从最小单位角度来看,整数的最小单位是1,所以整数可以精确表示,但是小数没有最小单位,所以不能精确表示。然而诸如0.5,0.25这样的数是可以精确表示的,所以可以进行比较。
所以,浮点型比较时尽可能不用使用==。
为了进行等量比较,只能先确定可接受的精度范围,再去进行比较。如下:
const double ACCEPT_DELTA = 0.000001;
bool equalDecimal(double num1, double num2)
{
if(fabs(num1 - num2) < ACCEPT_DELTA)
return true;
else
return false;
}
以前一直没意识到这个小问题,对一些问题必须从底层来看,才会比较容易理解。
- 我的github上博客:http://zealerww.github.io/
- github主页:https://github.com/zealerww