传递0.0时,减去浮点数会出错。
|
以下程序:
#include <stdio.h>
int main()
{
double val = 1.0;
int i;
for (i = 0; i < 10; i++)
{
val -= 0.2;
printf(\"%g %s\\n\", val, (val == 0.0 ? \"zero\" : \"non-zero\"));
}
return 0;
}
产生以下输出:
0.8 non-zero
0.6 non-zero
0.4 non-zero
0.2 non-zero
5.55112e-17 non-zero
-0.2 non-zero
-0.4 non-zero
-0.6 non-zero
-0.8 non-zero
-1 non-zero
有人能告诉我从0.2减去0.2时是什么引起错误的吗?这是舍入错误还是其他?最重要的是,如何避免该错误?
编辑:鉴于5.55112e-17非常接近于零(感谢@therefromhere提供了该信息),看来结论是不必担心它。
没有找到相关结果
已邀请:
4 个回复
细瑞
脖呐
相当笨拙,所以让我们以十六进制形式查看它:
现在,让我们来看看从1.0重复减去该值会发生什么:
精确结果无法用双精度表示,因此将其四舍五入,得出:
以十进制表示,这恰好是:
现在我们重复该过程:
因此,我们看到浮点算术所需的累积舍入产生了您正在观察的非常小的非零结果。舍入是微妙的,但它是确定性的,不是魔术,也不是错误。值得花时间学习。
枫湃揩乾纲
陈獭
并且您(很可能)会发现您认为0.2的值不是0.2,而是一个数量相差很小的数字(实际上,在我的计算机上,它打印出0.20000000000000001110)。现在您了解了为什么永远无法达到0。 但是,如果让val = 12.5并在循环中减去0.125,则可能会达到零。