Java中double类型的增减操作有效范围是多少?
问题
我正在编写一个Java类用于跟踪小数,该类需要支持数值的增减操作。使用double类型存储该数值在小数值范围内表现正常,但我想明确它的操作极限。我原本打算通过运行一段程序,同时递增double和long类型变量,直到二者转换后不再相等来确定该范围,但这段程序运行耗时过长。程序代码如下:
double x = 0; long y = 0; while ((long)x == y) { x++; y++; } System.out.println("X: " + x); System.out.println("Y: " + y);
请问double类型在什么范围内无法通过递增或递减操作实际改变数值(即增减1无效)?我认为负数的递减操作也会存在类似的精度问题。
回答
double是64位IEEE 754标准浮点数,包含52位尾数位(加上隐含的1位,总共能表示53位二进制有效数字)。当数值的绝对值大于等于2^53(即9007199254740992)时,double无法精确表示所有整数,此时增减1操作会失效:
- 正数场景:当
x ≥ 9007199254740992时,执行x++不会改变x的值。因为此时double的最小可表示增量(ULP,最后一位有效位的单位)已经大于1,加1后无法被精确存储,数值保持不变。 - 负数场景:当
x ≤ -9007199254740992时,执行x--同样不会改变x的值,原理和正数侧完全对称。
你之前的循环耗时过长,是因为需要执行超过9万亿次迭代才能达到临界值,完全没必要通过循环测试——直接通过浮点数的精度规则就能计算出这个范围。
内容的提问来源于stack exchange,提问作者Stephen Ostermiller
相关产品推荐
相关产品推荐

