为什么使用 double 的 for 循环无法终止 [英] Why does for loop using a double fail to terminate
问题描述
我正在查看旧的考试题(目前是大学第一年),我想知道是否有人可以更彻底地解释一下为什么以下 for
循环在它结束时没有结束应该.为什么会发生这种情况?我知道它由于舍入错误或其他原因而跳过 100.0,但为什么呢?
I'm looking through old exam questions (currently first year of uni.) and I'm wondering if someone could explain a bit more thoroughly why the following for
loop does not end when it is supposed to. Why does this happen? I understand that it skips 100.0 because of a rounding-error or something, but why?
for(double i = 0.0; i != 100; i = i +0.1){
System.out.println(i);
}
推荐答案
数字 0.1 不能用二进制精确表示,就像 1/3 不能用十进制精确表示一样,因此你不能保证:
The number 0.1 cannot be exactly represented in binary, much like 1/3 cannot be exactly represented in decimal, as such you cannot guarantee that:
0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1==1
这是因为在二进制:
0.1=(binary)0.00011001100110011001100110011001....... forever
然而,double 不能包含无限精度,因此,正如我们将 1/3 近似为 0.3333333 一样,二进制表示也必须近似为 0.1.
However a double cannot contain an infinite precision and so, just as we approximate 1/3 to 0.3333333 so must the binary representation approximate 0.1.
在十进制中你可能会发现
In decimal you may find that
1/3+1/3+1/3
=0.333+0.333+0.333
=0.999
这是完全相同的问题.它不应该被视为浮点数的弱点,因为我们自己的十进制系统也有同样的困难(但对于不同的数字,使用 base-3 系统的人会发现我们很难表示 1/3 很奇怪).然而,这是一个需要注意的问题.
This is exactly the same problem. It should not be seen as a weakness of floating point numbers as our own decimal system has the same difficulties (but for different numbers, someone with a base-3 system would find it strange that we struggled to represent 1/3). It is however an issue to be aware of.
Andrea Ligios 提供的现场演示显示了这些错误的累积.
A live demo provided by Andrea Ligios shows these errors building up.
这篇关于为什么使用 double 的 for 循环无法终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!