2

可能的重复:
在 java 中使用 Doubles 保持精度

好的,所以我有以下代码块:

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.95
  • 0.8999999999999999
  • 0.8499999999999999
  • 0.7999999999999998
  • 0.7499999999999998
  • 0.6999999999999997

希望有人能够清楚地解释。我搜索了互联网,当我们以二进制形式存储浮点数时,我读到它与一些限制有关,但我仍然不太明白。解决我的问题并不重要,但我想了解这种行为。

4

4 回答 4

3

Java 使用IEEE-754浮点数。它们并不完全精确。著名的例子是:

System.out.println(0.1d + 0.2d);

...输出0.30000000000000004.

你所看到的只是这种不精确的症状。double您可以通过使用而不是提高精度float

如果您正在处理财务计算,您可能更BigDecimal喜欢floatdouble

于 2012-06-11T09:43:19.413 回答
3

float并且double精度有限,因为它的小数部分表示为 2 的一系列幂,例如 1/2 + 1/4 + 1/8 ...如果你有一个像 1/10 这样的数字,它必须是近似的。

出于这个原因,每当您处理浮点时,您必须使用合理的舍入,否则您会看到小错误。

例如

System.out.printf("%.2f%n", zoom);

为了最大限度地减少轮次误差,您可以改为计算旋转次数并将该int值除以 20.0。这样你不会看到舍入错误,而且速度更快,幻数更少。

于 2012-06-11T09:55:17.727 回答
0

float并且double有精度问题。我建议您看一下BigDecimal类。那应该解决精度问题。

于 2012-06-11T09:42:55.517 回答
0

由于十进制数(以及整数)可以有无数个可能的值,因此它们不可能使用标准格式精确映射到位。计算机通过限制数字可以假设的范围来规避这个问题。

例如,intjava 中的 an 不能表示大于Integer.MAX_VALUE或 2^31 - 1 的任何值。

对于十进制数,逗号后面的数字也有问题,也可能是无限的。这可以通过不允许所有十进制值来解决,而是限制为(智能选择的)可能性数量,基于 2 的幂。这会自动发生,但通常无需担心,您可以将 0.899999 的结果解释为 0.9。如果您确实需要明确的精度,您将不得不求助于其他可能有其他限制的数据类型。

于 2012-06-11T10:00:38.410 回答