我有这段代码:
com
为什么 long i = 0;
while (true) {
i += 10*i + 5;
System.out.println(i);
Thread.sleep(100);
}
在打印几次后会变为负片?如果超出范围,是否应该发生错误?
答案 0 :(得分:5)
如果在最大值之后增加一个数字,Java不会抛出错误。如果您希望出现此行为,可以使用Java 8中的Math.addExact(long x, long y)
方法。如果您通过ArithmeticException
,此方法将抛出Long.MAX_VALUE
。
Java没有抛出异常并且您收到负数的原因与数字的存储方式有关。对于长基元,第一个字节用于指示数字的符号(0 - >正,1 - >负),而其余字节用于数值。这意味着最大正值Long.MAX_VALUE
将被存储为01111 ... 111(0后跟63位1)。由于您向Long.MAX_VALUE
添加了一个数字,因此您将开始接收负整数,因为符号字节更改为1.这意味着您有一个数字溢出,但Java不会抛出此错误。
答案 1 :(得分:0)
如果操作溢出,结果将返回到最小值并从那里继续。
没有异常抛出。
如果您的代码可能会溢出,则可以使用BigInteger
代替。
答案 2 :(得分:0)
kill
javadoc的摘录:
"该平台使用带有int和long原始类型的带符号的二进制补码整数算法。开发人员应选择基本类型以确保算术运算始终如一地产生正确的结果,这在某些情况下意味着操作不会溢出计算值的范围。最佳做法是选择基本类型和算法以避免溢出。"
对于Java 8:
"如果大小为int或long并且需要检测溢出错误,则addExact,subtractExact,multiplyExact和toIntExact方法会在结果溢出时抛出ArithmeticException。对于其他算术运算,例如除法,绝对值,递增,递减和否定溢出仅在特定的最小值或最大值时发生,并且应根据适当的最小值或最大值进行检查"