本问题已经有最佳答案,请猛点这里访问。
Possible Duplicate:
Java floats and doubles, how to avoid that 0.0 + 0.1 + … + 0.1 == 0.9000001?
我在Java中遇到以下问题-我需要以0.1f的增量在0.1f和1.0f之间进行迭代,因此我希望输出如下所示:
0.1
0.2
0.3
0.4
...
0.9
相反,当我这样做时:
for(float i = 0.1f; i < 1f; i += 0.1f)
System.out.println(i);
我懂了
0.1
0.2
0.3
0.4
0.5
0.6
0.70000005
0.8000001
0.9000001
我想这与计算机表示分数的方式有关,但是我想知道为什么会这样,以及是否有什么办法可以阻止它。
谢谢。
您可以改用双打吗?
确实,这根本不可行。 没有确切的值0.1可表示为浮点数或双精度数。
"我想知道这是为什么"-简短的答案是"舍入误差"。 要获得较长的答案,请阅读以下内容-docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html。" ...如果有什么我可以阻止的事情"-简短回答"不"。
在for循环中使用整数,以避免重复的浮点数学运算,这会增加浮点错误。
for (int i = 1; i < 10; i++)
{
float f = (float) i / 10.0f;
System.err.println(f);
}
您可以尝试以下方法:
for(int i = 1; i < 10; i++)
System.out.println(i/10f);
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
您所看到的是浮点数固有的不准确性的结果,如果您不断添加它们,这些自然就会累积,就像在发布的代码中所做的那样。 如果改为在循环中使用int,则避免进行float加法运算,因此也避免了错误累积。
为什么要投反对票?
我不是那个否决这个答案的人,但是如果我猜出来的话,因为您的输出以0.0开头,而不是0.1开头。
@rgettman啊,是的-更改了1个字符,感谢您指出。我真的希望投票者会发表评论以表明这些事情。
浮点数是二进制的,不能很好地表示小数
如果适用,则以1/8或0.125进行迭代。
for(float i =1.0f;i<10f;i+=1f)
System.out.println(i/10f);`
很丑陋,但可以在这里使用(Ubuntu AMD64 OpenJDK)
浮动我?????????
引用我自己:这很丑陋,但是在这里有效。
嗯...看起来/听起来像是我的伏都教解决方案。
引用自己:这很丑陋,但是在这里有效
...只要您继续牺牲鸡!!"它似乎行之有效",而没有清楚地理解为什么编写脆弱的,无法维护的代码。我们应该不鼓励新程序员使用这种编程方法……而不是向他们提供我们自己的伏都教编程"解决方案"以复制到他们的代码中。
精彩。如果没有可用的鸡肉,则可以替代被诅咒的鸭子。这是我提到的"但可以在这里使用(Ubuntu AMD64 OpenJDK)":我不知道它是否可以在x86上运行(并且我不在乎)。对发生的情况的理解是微不足道的:1/10在任何二进制浮点数中都无法表示,无论精度如何。我不鼓励任何人(无论有经验的人)尝试使0.1成为一个精确的浮点数..它只会起作用。我要说的是:这在指定的确切情况下有效。再多一点。