双精度浮点数的最大整数值

4
这是Java中可以分配给double的最大整数值,同时仍然作为整数值行为的限制?我是说,它仍然必须满足通常的条件。
a + 1 > a;
a - 1 < a;

如果值足够大,即使是a+1000也可能因为舍入误差而等于a

我需要使用double作为计数器,并想知道可靠计数的上限在哪里。


5
为什么要使用double而不是long?或者甚至是BigInteger如果你真的需要很大的值? - JB Nizet
另一种解决方案是使用一个任意精度算术库,比如http://www.apfloat.org/apfloat_java/。 - x4rf41
为什么不写一个程序试试呢?编写一个5行Java程序,循环和测试并不难。 - Charles Goodwin
你不能将1加到最大值上并得到一个有意义的值。MAX_VALUE + 1 = undefined。 - DwB
1
这个问题是关于Java的double类型,而不是C语言的double类型。而且C语言的double类型的大小是由具体实现决定的。 - Audrius Meškauskas
3个回答

4
您要寻找的数字是9,007,199,254,740,991,因为9,007,199,254,740,991 + 1 = 9,007,199,254,740,992,但9,007,199,254,740,992 + 1 = 9,007,199,254,740,992
我使用以下代码进行实验。
double a = 9.007199254E15;
while (a + 1 > a) {
    a += 1;
}
System.out.println(a);

考虑到您将使用此值作为计数器,以及longs的最大值为2^63 - 1 = 9.22E18(正如Peter所指出的那样),似乎没有理由不使用longs。


可能更清晰的写法是 9,007,199,254,740,992(或者根据你所在国家的习惯,写成 9 007 199 254 740 992)。 - Ted Hopp
这个理论也支持这一点:double类型大约有16位有效数字(约为15.955)。int类型最多有10位有效数字,因此只要您在32位整数范围内,+1总会改变该值。对于64位整数,该值会发生变化(long类型最多有19位有效数字)。 - x4rf41
一个 double 类型的尾数有 53 位,所以它的最大值是 2 的 53 次方。 - Mark Elliot
我也尝试了这段代码并确认。9.007199254740992E15。 - Audrius Meškauskas
这可能是正确的,但仅基于该测试,您不能确定地说。您无法证明对于每个小于那个整数的int,a+1>a都成立。要这样做,您必须分析JRE中double的表示并在数学上证明它。 - Danubian Sailor

4
我需要使用double作为计数器,并想知道可靠计数的上限在哪里。
我无法想象为什么要使用double作为计数器来存储整数,但上限应该在八百万亿(2 ^ 53)范围内。如果您使用long作为计数器,则上限为9千亿亿。

看起来限制恰好是2^53!你是怎么找到那个值的? - wheels
1
@wheels - 请参考机器精度的维基百科页面 - Ted Hopp
@wheels 2^53-1是最大的数字,其中所有位都适合于尾数,并且2^53也可以工作,因为它是2的幂,并且尾数全为零,再多一个就无法准确存储该值。 - Peter Lawrey

1
如果您说的是整数,即int,那么所有可能的int值都适合于double中,因为int被定义为32位有符号整数量,而double的尾数大小为53位(可以轻松容纳int值)。另一方面,如果您指的是long,那么情况就不同了,因为long是64位有符号整数量。

可表示的最大长整型值应该是2的53次方-1左右(没有尝试,所以可能是错误的)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接