2013-04-01 175 views

回答

6

Java使用64位IEEE-754表示,所以最接近的数量小于一个理论上3FEFFFFFFFFFFFFF十六进制表示,这对于符号为0,对于指数为-1,对于52位有效位为1.9999999999999997。这大致等于0.9999999999999998

参考文献:IEEE-754 Calculator

+1

关于0.9999999999999999呢?它有相同的数字位数,但是最后有一个9而不是8。当我'System.out.println(0.9999999999999999 - 0.9999999999999998)',我得到:1.1102230246251565E-16 – Justin

+1

@gangqinlaohu最后一位数字不准确。我截取了从IEEE-754计算器获得的数字(请参阅答案中的链接)以获取数字。 8之后的下一个数字也是8,所以如果应用舍入,结果变为0.9999999999999999。 – dasblinkenlight

+1

呵呵,所以0.9999999999999999比0.9999999999999998更接近,因为0.9999999999999998被截断了,所以最靠近1的Double是0.9999999999999999。 – Justin

0

双数的最小正值为Double.MIN_NORMAL。所以,小于1.0的最大数字是1.0-Double.MIN_NORMAL

Double.MIN_NORMAL等于2 -1022,所以答案是仍然极其接近1.0。你必须要打印的1.0-Double.MIN_NORMAL到308位小数的价值之前,你可以看到什么,但9

+2

奇怪的是,当我在System.out.println中包装'1.0 - Double.MIN_NORMAL == 1.0'时,我变为true。但是当我在System.out.println中包含0.9999999999999999时,我得到了错误。那么这是否意味着0.9999999999999999是最接近的两倍? – Justin

+0

哼...不,所以,MIN_NORMAL适用于值_closest到零_这是IEEE-754值上可能出现的最小错误。但是,因为你走向1,一些精度会丢失! – mjv

+0

'System.out.println(Double.MinNormal)'给出了2.2250738585072014E-308。很小。 – Justin

4

你想要的数字是由Math.nextAfter(1.0, -1.0)返回的。

该函数的名称有点用词不当。 Math.nextAfter(a, 1.0)返回至少两倍值大于a(即,a之后的下一个值),并返回Math.nextAfter(a, -1.0),其小于a最大值(即,值之前a)。

注:另一张海报说,1.0-Double.MIN_NORMAL。这是错误的。 1.0-Double.MIN_NORMAL正好等于1.0。