在《算法竞赛入门经典(第二版)》(紫书)的第二章,最后有一道思考题:
下面的程序运行结果是什么?提示:请上机实验,不要凭主观感觉回答。
#include<stdio.h>
int main() {
double i;
for (i = 0; i != 10; i += 0.1)
printf("%.1f\n", i);
return 0;
}
实验发现程序会无限循环执行下去,即使把10换成10.0也没有用。
这就是程序的浮点数陷阱。
我们知道,计算机底层存储数据是二进制的。如果学过计组的同学会知道,整数计算还好,小数计算会由于精度问题出现舍入,导致计算结果与真实值出现细微偏差。
也就是说,1.1 + 0.1并不一定会按照我们预想的得到1.2,也有可能会得到0.120……01。
因此我们不应该依靠==对浮点数进行恒等判断。
总结:
- 循环的条件变量应当是整形的。事实上它也没有理由应该是其他类型的,难道我们要循环0.5次吗?
- 在判断两个浮点数a和b是否相等时,不要用a==b。作为替代,可以计算两者之差的绝对值
fabs(a-b)
是否小于某个阈值,例如if(fabs(a-b) < 1e-9)
。