因此,当我使用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
答案 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
如果必须使用double
,则可以减少浮点错误
使用Kahan Summation Algorithm。
答案 1 :(得分:2)
在Java中,双精度使用IEEE 754浮点运算(参见this维基百科文章),这本质上是不准确的。使用BigDecimal获得完美的小数精度。要使打印成圆形,只接受“非常好”的准确性,请使用printf("%.3f", x)
。