1

我目前正在使用 java 中的一个程序,该程序需要将一个小的常量值(例如 0.00000000001)添加到一个双变量,例如。地点。但是,当我运行代码时,对其进行调试,然后到达我将 0.00000000001 添加到位置的位置,并在添加后在调试模式下检查位置的值。该位置似乎没有添加 0.00000000001。例如,位置在添加之前等于 438.0,在添加之后等于 438.0。这是简单代码的示例

位置 += 0.00000000001

有任何想法吗?提前致谢。

4

7 回答 7

6

由于存储方式的原因,许多双精度值在 Java 中并不完全精确。精确精度仅适用于某些值。这是因为 Java 只能将十进制值存储为许多 2^n (s) 的组合。

例如:1/4可以存储为2^-2,但1/3将存储为2^-2 + 2^-3+ 2^-4 +2^-5...,因此1/3是一个不完全精确的值的示例

如果您想要一个精确的值,请使用BigDecimal该类:

http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

于 2012-06-13T14:45:34.903 回答
5

您需要使用BigDecimal以获得更好的精度。

例子:

BigDecimal test = new BigDecimal(438.0);
test = test.add(new BigDecimal(0.0000000000001));
System.out.println(test);
于 2012-06-13T14:45:45.080 回答
4

使用 BigDecimal 类。它具有任意精度,并且能够处理微小的值。

于 2012-06-13T14:45:58.943 回答
2

如果您超过double添加非常小的值的精度,则不会执行任何操作。

for (double d = 438; d < 1e7; d *= 10) {
    double location = d;
    location += 0.00000000001;
    System.out.println(location);
}

印刷

438.00000000001
4380.00000000001
43800.00000000001
438000.0
4380000.0
于 2012-06-13T14:46:05.387 回答
1

您可能遇到了舍入错误或下溢。我会尝试使用BigDecimal来获得任意精度。

于 2012-06-13T14:47:36.873 回答
1

你应该阅读http://firstclassthoughts.co.uk/java/traps/java_double_traps.html

这涉及到 java 如何存储和处理双精度和浮点数,以及在使用和比较它们时它们的含义。

这基本上是一个“你看到的不是你得到的”的例子

如果你决定使用大十进制,这有它自己的陷阱案例

http://firstclassthoughts.co.uk/java/traps/big_decimal_traps.html

这真的归结为您要添加 0.00000000001 做什么?

于 2012-06-13T14:53:34.727 回答
0

还有一件事要添加到另一个答案中。问题不在于值太小。更大的价值=更大的不公平。看一个例子:

 float x = 20000000.0f;
 for (int i = 0; i < 10000000; i++) {
     x += 1;
 }
 System.out.println(x); // prints 20000000.0f, not 30000000.0f!

因此,如果您在循环中使用浮点数,您将永远无法退出此循环

于 2012-06-13T16:26:28.750 回答