为什么这些简单的双重比较会返回 true?
System.out.println(Double.MAX_VALUE == (Double.MAX_VALUE - 99 * Math.pow(10, 290)));
System.out.println(new Double(Double.MAX_VALUE).equals(new Double(Double.MAX_VALUE - 99 * Math.pow(10, 290))));
我知道这可能是 IEEE 754
精度问题,但我无法弄清楚这里的确切问题是什么。
最佳答案
非常大的 float 非常不精确。您看到的是舍入误差。
我们可以演示以 10 为基数(科学记数法)的 float ,比如指数为 1 位,底数为 4 位:
1234*10^1 == 1234
1234*10^-1 == 123.4
1234*10^9 == 1,234,000,000,000
1235*10^9 == 1,235,000,000,000
由此可见:
1234*10^9 - 1234*10^1 == 1234*10^9
您可以看到,随着数字变大,我们会失去精度。很多。
对于kicks,可以测试一下:
double d = 10;
while(Double.MAX_VALUE - d == Double.MAX_VALUE)
d *= 10;
System.out.println(d);
我们可以确定 Double.MAX_VALUE
和下一个最小值(称为 ULP )之间的差距在 10^292
左右,这是一个非常差距大。
我们可以借助 Math#ulp
确定它的确切值:
long lng = Double.doubleToRawLongBits(Double.MAX_VALUE);
double nextMax = Double.longBitsToDouble(lng - 1);
System.out.println(Math.ulp(nextMax));
这大约是 1.99584*10^292
,或 2^971
。
关于java - 将 Java Double.Max_VALUE 与大双数进行比较返回 true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27007763/