添加和减去双打会产生奇怪的结果

时间:2013-03-25 21:55:18

标签: java double

因此,当我使用Doubles在Java中添加或减去时,它会给我带来奇怪的结果。以下是一些:

如果我添加0.0 + 5.1,则会向我5.1。那是对的。

如果我添加5.1 + 0.1,它会给我5.199999999999(重复9的数量可能会关闭)。那是错的。

如果我减去4.8 - 0.4,它会给我4.39999999999995(同样,重复的9可能会关闭)。那是错的。

起初我认为这只是添加带小数值的双打的问题,但我错了。以下工作正常:

5.1 + 0.2 = 5.3
5.1 - 0.3 = 4.8

现在,添加的第一个数字是保存为变量的double,尽管第二个变量从JTextField获取文本。例如:

//doubleNum = 5.1 RIGHT HERE
//The textfield has only a "0.1" in it.
doubleNum += Double.parseDouble(textField.getText());
//doubleNum = 5.199999999999999

2 个答案:

答案 0 :(得分:25)

在Java中,double值为IEEE floating point numbers。除非它们是2的幂(或2的幂的总和,例如1/8 + 1/4 = 3/8),否则即使它们具有高精度,也不能精确地表示它们。某些浮点运算会使这些浮点数中出现的舍入误差复杂化。如上所述,浮点错误已经变得非常重要,可以显示在输出中。

数字的来源是什么,无论是从JTextField解析字符串还是指定double文字都无关紧要 - 问题是在浮点表示中继承。< / p>

解决方法:

  • 如果您知道您只有这么多小数点,那么请使用整数 算术,然后转换为小数:

    (double) (51 + 1) / 10
    (double) (48 - 4) / 10
    
  • 使用BigDecimal

  • 如果必须使用double,则可以减少浮点错误 使用Kahan Summation Algorithm

答案 1 :(得分:2)

在Java中,双精度使用IEEE 754浮点运算(参见this维基百科文章),这本质上是不准确的。使用BigDecimal获得完美的小数精度。要使打印成圆形,只接受“非常好”的准确性,请使用printf("%.3f", x)