Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 双减法精度问题_Java_Double - Fatal编程技术网

Java 双减法精度问题

Java 双减法精度问题,java,double,Java,Double,我的同事做了这个实验: public class DoubleDemo { public static void main(String[] args) { double a = 1.435; double b = 1.43; double c = a - b; System.out.println(c); } } 对于这个一级操作,我期望得到以下输出: 0.005 但出乎意料

我的同事做了这个实验:

public class DoubleDemo {

      public static void main(String[] args) {
           double a = 1.435;
           double b = 1.43;
           double c = a - b;
           System.out.println(c);
      }
 }
对于这个一级操作,我期望得到以下输出:

0.005
但出乎意料的是,结果是:

0.0050000000000001155

为什么double在这么简单的操作中失败了?如果double不是这项工作的数据类型,我应该使用什么呢?

double和float不完全是实数

在任何范围内都有无穷多的实数,但表示它们的位数是有限的因此,双精度浮点和浮点的舍入误差是预期的

您得到的数字是最接近的数字,在浮点表示法中可以用double表示

有关更多详细信息,请阅读[警告:可能是高级别的]


您可能希望使用获取精确的十进制数[但当您尝试获取
1/3
]时,您将再次遇到舍入错误。

double
在内部以二进制小数形式存储,如
1/4+1/8+1/16+…

0.005
——或值
1.435
——不能存储为二进制的精确分数,因此
double
不能存储精确值
0.005
,减去的值也不太精确

如果您关心精确的十进制算法,请使用
BigDecimal


你也可以找到有用的阅读资料。

double
float
算法永远不会完全正确,因为“在引擎盖下”会发生舍入

从本质上讲,double和float可以有无限数量的小数,但在内存中,它们必须由一些实数位数表示。所以,当你做这个十进制算术时,会发生一个舍入过程,如果你把所有的小数都考虑进去,舍入过程通常会减少一个非常小的数值


如前所述,如果您需要完全精确的值,则使用以不同方式存储其值的
BigDecimal

是的,它使用BigDecimal操作以这种方式工作

private static void subtractUsingBigDecimalOperation(double a, double b) {
  BigDecimal c = BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b));
  System.out.println(c);
}

输出

使用double时2.15和1.0之间的差异为:1.0499999998
2.15和1.0之间使用BigDecentral的区别是:1.05

感谢分享您的实验+1可能的重复并不能回答这个问题。嗯,你是对的。试着做一些关于BigDecimal的小例子。已经有人在回答这个问题了。不需要重复。因此,答案是为了提供一个完整的、自包含的答案。如果你觉得另一个答案遗漏了什么,在你有足够的声誉后留下评论。如果你认为你能写出一个更好的完整答案,那就这么做吧。不要发布像这样的“半答案”。这不好,因为它只是设置值,不适用于负值。说它们“永远”不会完全正确是不准确的。正确的说法是,除了分母不是二的幂的分数之外,它们永远不会完全正确。我有一个问题,如果我们有一个double,我们在做算术运算之前把它转换成BigDecimal,它会工作吗?不过我要检查一下自己:)@muasif80:不,不会的。如果你想做精确的算术,千万不要碰一个
双精度的
。好的,谢谢。我尝试了下面分享的一个例子。但我会尽量听从你的建议,“分数之和”这个概念从何而来?你通常有指数和尾数,因此表示的值是V=(2^e)*(1.m)@Jack:是的。你认为
m
是什么?
BigDecimal.valueOf
对一些
double
值有效,但不是全部。Ok。我必须首先检查double值是如何出现的,然后是在我的特殊情况下。我将根据你的见解改变这一点。谢谢你的回复。
private static void subtractUsingBigDecimalOperation(double a, double b) {
  BigDecimal c = BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b));
  System.out.println(c);
}
public class BigDecimalExample {

    public static void main(String args[]) throws IOException {

      //floating point calculation
      double amount1 = 2.15;
      double amount2 = 1.10;
      System.out.println("difference between 2.15 and 1.0 using double is: " + (amount1 - amount2));

      //Use BigDecimal for financial calculation
      BigDecimal amount3 = new BigDecimal("2.15");
      BigDecimal amount4 = new BigDecimal("1.10") ;
      System.out.println("difference between 2.15 and 1.0 using BigDecimal is: " + (amount3.subtract(amount4)));       
    }      
}