java双重计算

时间:2012-10-26 20:27:44

标签: java double

我知道计算机不能精确地表示非整数。所以当我在java中添加2个双打时,例如:

724.64d + 1000d

控制台打印出1724.6399999999999

724.64d + 100d724.64d + 10000d

的原因

控制台分别打印824.64和10724.64?

有没有办法知道在我添加2个双打的情况下,总和是确切的数字?

我问的原因是因为我们的旧程序使用double来进行计算。并使用双重比较来验证数字。 例如:我们说总数为1849.64,所有输入的金额必须等于总数1849.64

input 1: 724.64
input 2: 1125

不起作用,因为总和将是1849.6399999999999

但如果我们这样输入下面的话会有效,总和是1849.64

input 1: 24.64
input 2: 1825

那么如何找到有效的组合呢? 注意,我无法访问这个特定的非常旧的程序。当验证失败时,我们必须手动找到像第二个输入组合一样的走动。 感谢。

5 个答案:

答案 0 :(得分:2)

BigDecimal bigDecimal = new BigDecimal(724.64);
bigDecimal = bigDecimal.add(new BigDecimal(1000.0));
System.out.println(bigDecimal.floatValue());<--Works fine 
System.out.println(bigDecimal.doubleValue());<--Works as mentioned in Question

输出:

1724.64
1724.6399999999999

在第一种情况下,由于narrowing primitive conversion发生,它起作用。但是对于浮点数,您将不得不接受并使用它。

正如我所说,它对原语有效

double d = 724.64;
double d1 = 1000.0;
System.out.println(d + d1);
System.out.println((float) (d + d1));

输出:

1724.64
1724.6399999999999

答案 1 :(得分:1)

浮点数不代表十进制数字,但在二进制系统中显然只有有限精度,因此十进制表示的精确值与浮点数之间存在不匹配代表。你不能指望它这样做。

答案 2 :(得分:1)

考虑在这些情况下使用BigDecimal,而不是尝试确定导致精确或不精确计算的条件。

答案 3 :(得分:1)

要回答你的最后一个问题,如果小数部分是2的负幂,则双精度是精确的,例如0,1 / 2,1 / 4,1 / 16 ......,它将出现在某些其他情况下(如您发布的那些),如果用于将它们转换为十进制的API(例如System.out.println())进行舍入或截断,并且值足够接近舍入或截断产生预期的答案。

答案 4 :(得分:0)

如果比较是问题,作为解决方法,我建议格式化字符串中的数字2位小数并完成舍入,然后比较字符串:

        double expectNum = 1849.64;
        double resultNum = 1849.639999;

        String expectedString = String.format("%.2g%n", expectNum);
        String resultString = String.format("%.2g%n", resultNum);

        if(expectedString.equals(resultString)){
           //result matched
           //return true;
        }else{
           //return false;
        }