为什么这些简单的双重比较返回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精度问题,但我不知道到底是什么问题。
发布于 2014-11-19 02:20:32
非常大的浮点数是,非常不精确。你看到的是舍入错误。
我们可以用基-10(科学表示法)演示浮点,例如指数用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你可以看到,当数字变大时,我们就失去了精度。好多了。
对于踢腿,你可以测试它:
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的。
发布于 2014-11-19 02:23:23
浮点数越大,一个浮点数和下一个浮点数之间的差距就越大。这是因为,在测量值1时,误差0.5是非常重要的,但在测量值1000000000000时,误差却是微不足道的。
Double.MAX_VALUE是巨大的,你从它中减去的数字就不那么庞大了。事实上,差别很大,你要减去的数字比Double.MAX_VALUE和下一个双降之间的差距要小,所以Double.MAX_VALUE是最接近精确结果的可表示的数字。因此,您只需拿回Double.MAX_VALUE。
发布于 2014-11-19 02:19:34
我认为问题就在这条线上
|
v
new Double(Double.MAX_VALUE).equals(new Double(Double.MAX_VALUE - 99999999999999999999999D))双MAX_VALUE = Double.MAX_VALUE -999999999999999999999999999D
你把它和
新双(Double.MAX_VALUE-9999999999999999999999999999999999D)
我认为这是一样的,所以它将永远返回真。
https://stackoverflow.com/questions/27007763
复制相似问题