5

这只是出于好奇。如果我将两个递归数或无理数存储在两个双精度数中,然后执行一些操作,它如何产生实际结果?

例如,

double d1=7d/3;
double d2=5d/3;
double sum=d1+d2;
System.out.println(new BigDecimal(sum)); //prints exactly 4

另一个:

double d1=log10(3);
double value=Math.pow(10,d1);
System.out.println(new BigDecimal(value)); //prints exactly 3

这些准确的结果是如何产生的?

4

1 回答 1

5

如果你稍微修改你的代码,你会看到它d1并不d2完全是7/3or 5/3d1+d2确切的原因4是它4可以精确地表示为双精度,并且最接近此加法的确切结果。

public static void main(String[] args) throws Exception {
    double d1 = 7d / 3;
    double d2 = 5d / 3;
    System.out.println(new BigDecimal(d1)); //2.333333333333333481363069950020872056484222412109375
    System.out.println(new BigDecimal(d2)); //1.6666666666666667406815349750104360282421112060546875
    System.out.println(new BigDecimal(d1).add(new BigDecimal(d2))); //4.0000000000000002220446049250313080847263336181640625
    double sum = d1 + d2; 
    System.out.println(new BigDecimal(sum)); //4
}

Java遵循 IEEE 754 约定

使用 IEEE 754 舍入到最近模式将总和舍入到所选值集中的最接近值

于 2012-10-20T07:03:35.413 回答