好的,所以我有以下代码:
int rotation = e.getWheelRotation();
if(rotation < 0)
zoom(zoom + rotation * -.05);
else if(zoom - .05 > 0)
zoom(zoom - rotation * .05);
System.out.println(zoom);
现在,zoom变量的类型为double,最初设置为1.因此,我希望结果类似于1 - .05 = .95; .95 - .05 = .9; .9 - .05 = .85;虽然我打印结果时看起来并非如此,如下所示:
希望有人能够清楚地解释。我在互联网上搜索,当我们用二进制文件存储浮点数但我仍然不太明白时,我读到它与某些限制有关。我的问题的解决方案并不重要,但我想了解这种行为。
答案 0 :(得分:3)
Java使用IEEE-754个浮点数。它们并不完全准确。着名的例子是:
System.out.println(0.1d + 0.2d);
...输出0.30000000000000004
。
你所看到的只是那种不精确的症状。您可以使用double
而不是float
来提高精确度。
如果您正在处理财务计算,您可能更喜欢BigDecimal
到float
或double
。
答案 1 :(得分:2)
float
和double
的精确度有限,因为其小数部分表示为2的一系列幂,例如1/2 + 1/4 + 1/8 ......如果你有一个像1/10的数字,它必须近似。
出于这个原因,每当你处理浮点数时,你必须使用合理的舍入,否则你会看到很小的错误。
e.g。
System.out.printf("%.2f%n", zoom);
为了最大限度地减少轮次错误,您可以计算转数,并将此int
值除以20.0。你不会以这种方式看到舍入错误,并且它会更快,而且数量更少。
答案 2 :(得分:0)
float
和double
存在精确问题。我建议你看看BigDecimal班级。这应该解决精确问题。
答案 3 :(得分:0)
由于十进制数字(以及整数数字)可以具有无限数量的可能值,因此无法使用标准格式精确地映射到位。计算机通过限制数字可以采用的范围来解决这个问题。
例如,java中的int
可以表示大于Integer.MAX_VALUE
或2 ^ 31 - 1的任何内容。
对于十进制数字,逗号后面的数字也有问题,也可能是无限的。这可以通过不允许所有十进制值来解决,但是基于2的幂限制到(智能选择的)可能性的数量。这会自动发生但通常无需担心,您可以将0.899999的结果解释为0.9。如果您确实需要显式精度,则必须使用其他数据类型,这可能有其他限制。