Java 双精度的加减运算产生了奇怪的结果

Java 双精度的加减运算产生了奇怪的结果,java,double,Java,Double,所以,当我在Java中用double进行加法或减法运算时,会得到奇怪的结果。以下是一些: 如果我添加0.0+5.1,它会给我5.1。没错 如果我添加5.1+0.1,它会给我5.19999999999(重复9s的次数可能已关闭)。那是错误的 如果我减去4.8-0.4,它将给出4.3999999995(同样,重复的9s可能会关闭)。那是错误的 起初,我以为这只是用十进制值加双精度的问题,但我错了。以下措施效果良好: 5.1 + 0.2 = 5.3 5.1 - 0.3 = 4.8 现在,添加的第一个

所以,当我在Java中用double进行加法或减法运算时,会得到奇怪的结果。以下是一些:

如果我添加
0.0+5.1
,它会给我
5.1
。没错

如果我添加
5.1+0.1
,它会给我
5.19999999999
(重复
9
s的次数可能已关闭)。那是错误的

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

起初,我以为这只是用十进制值加双精度的问题,但我错了。以下措施效果良好:

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

在Java中,
double
值为。除非它们是2的幂(或2的幂和,例如1/8+1/4=3/8),否则即使它们具有高精度,也无法精确表示。某些浮点运算会使这些浮点数中存在的舍入错误变得复杂。在上面描述的情况下,浮点错误已经变得非常严重,足以显示在输出中

不管数字的来源是什么,不管是解析
JTextField
中的字符串还是指定
double
文本,问题都在于浮点表示中的继承

解决办法:

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

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

  • 如果必须使用双精度,则可以减少浮点错误 用这个


在Java中,Double使用IEEE 754浮点算法(参见Wikipedia文章),这本质上是不准确的。用于完美的十进制精度。要在打印中取整,只接受“相当好”的精度,请使用
printf(“%.3f”,x)

你认为如果我使用
float
s,它会给出更精确的值吗?一个
float
通常只有
双精度的一半。如果你需要准确度,那可不是个好主意。@Ingo:接得好;我已经更新了我的答案。顺便说一句,我更喜欢使用BigDecimal(),实际上是5.19999999。。。(有无限多个重复的9)在数学上与5.2完全相同,如果你不相信,试着找出两者之间的区别。它是0,因此,它们是相同的。@Ingo从技术上讲,是的,但我想得到一个稍微精确的答案:)Rob,我理解,我发现这些数字被称为“浮点”和“双精度”非常遗憾。适当的名称应为“粗略近似”和“稍好,但仍然粗略近似”