我尝试理解以下代码:
int i = Integer.MAX_VALUE;
double d = Double.MAX_VALUE;
System.out.println(i + ":" + (i+1));
System.out.println(d + ":" + (d+1));
输出结果为:
2147483647:-2147483648
1.7976931348623157E308:1.7976931348623157E308
对于第一行,i
等于最大整数,并且递增它会导致最小的整数值。为什么d
没有发生同样的情况?
这种行为有简单的解释吗?
答案 0 :(得分:2)
当双重溢出时,其值变为Infinity
,而不是负数。
仅仅向Double.MAX_VALUE
添加1就无法溢出的原因是MAX_VALUE + 1 == MAX_VALUE
,因为双精度不足以使这两个数字之间存在差异。
实际上你可以在跳到下一个可用的双倍之前添加相当多的数字。例如,它不会溢出:
System.out.println(Double.MAX_VALUE + 1e100); //still Double.MAX_VALUE
这会按预期溢出:
System.out.println(m + (Math.ulp(m) / 2)); //Infinity
答案 1 :(得分:1)
您的double
无法代表您尝试代表的实际号码,因为double
的精确度会下降。这就是价值没有变化的原因,而且您实际上没有有溢出。
对于非int
类型,溢出将导致 Infinity 。例如,尝试将该值乘以20,并且您将看到溢出效应。
答案 2 :(得分:1)
整数溢出,因为它以two's complement格式表示。
Integer.MAX_VALUE
由0111...111
Integer.MIN_VALUE
由1000...000
因此,当您尝试向Integer.MAX_VALUE
添加1时,根据正常的添加规则,您会获得Integer.MIN_VALUE
。这称为溢出。
浮点数具有不同的表示形式,不适用于此类溢出。它们都是近似值,它与您给出的值的最接近的近似值是Double.MAX_VALUE
。