Java Double变量有奇怪的值

时间:2011-12-14 20:37:46

标签: java double division

  

可能重复:
  Floating point arithmetic not producing exact results in Java

我正在做这个简单的分工,但我得到一个非常奇怪的输出:

double a = 60/(1.2-1.1);

a => 600.0000000000008

什么时候应该是600。

提前致谢

6 个答案:

答案 0 :(得分:8)

在IEEE-754二进制双精度中,我们需要考虑二进制表示中的1.1和1.2:

1.2 = 0b1.001100110011001100110011001100110011001100110011001100110011...
1.1 = 0b1.000110011001100110011001100110011001100110011001100110011001...

请注意,我们需要无限多位来完全用二进制表示它们。 double只有53位的重要性,我们必须砍掉这些数字:

1.2 = 0b1.001100110011001100110011001100110011001100110011001100110011...
1.1 = 0b1.000110011001100110011001100110011001100110011001100110011001...
                                                              ^ round from here
==>
1.2 ~ 0b1.0011001100110011001100110011001100110011001100110011
      (= exactly 1.1999999999999999555910790149937383830547332763671875)
1.1 ~ 0b1.0001100110011001100110011001100110011001100110011010
      (= exactly 1.100000000000000088817841970012523233890533447265625)

因此1.2 - 1.1是:

  1.2 ~ 0b1.0011001100110011001100110011001100110011001100110011
- 1.1 ~ 0b1.0001100110011001100110011001100110011001100110011010
————————————————————————————————————————————————————————————————
        0b0.00011001100110011001100110011001100110011001100110010000
        (= exactly 0.09999999999999986677323704498121514916419982910156250000)

我们实际上可以准确计算60 / 0.0999999999999998667732370449812151491641998291015625,这给出了

600.0000000000007993605777301137740672368493927467455286920109359612256820927...
                ^ 16th significant figure

匹配OP的

结果
600.0000000000008

答案 1 :(得分:5)

因为double原语是floating point数据类型,它可以交换精度以保存更大范围的值。

如果您需要任意精确度,则应使用BigDecimal代替。

答案 2 :(得分:4)

你已经发现了浮点运算的奇迹。由于数字的内部表示是二进制的,因此无法精确表示某些十进制数。因此,某些算术运算会在最低有效数字中产生意外结果。

例如,在数值方法课程中详细介绍了这一点,但Wikipedia article并不错。

答案 3 :(得分:2)

您可能应该阅读"What Every Computer Scientist Should Know About Floating-Point Arithmetic"

简而言之,并非所有真实值都可以用double,精确表示,因此在需要确切答案时应避免使用它们。

答案 4 :(得分:2)

您应该使用 BigDecimal 来获得正确的结果。

答案 5 :(得分:1)

这不是一个“四舍五入的问题”。某些数字不能用二进制浮点精确表示。就像1/3不能用十进制精确表示,因为没有人有无限的纸张供应。 (或位)。