我试图检查不同的输入并在java中创建无限循环,我发现一旦int超过最大限制递增,它就会变成负数-2147482958。 我只是在无限循环中增加int ...
码:
public static void infiniteLoop(){
for(int i=0;i>-1;i++){
i = i + 1000;
System.out.println(i);
}
}
最后输出的价值是,
2147483337
-2147482958
现在,为什么会变成负数?
谷歌"双补"
如果您想被当真,则应该更改标题。
@Junuxx我照顾好了。
@all,真的很抱歉,没有什么幽默感。 我知道它很重要,我正在阅读有关停止问题的信息,而我很沮丧,因为没有找到一种方法来检查是否可以通过给定的输入来检测程序是否停止了:)
@bmargulies,谢谢,再次抱歉!
Why does it goes to negative?
因为这是int计算溢出时在Java中指定发生的情况。
JLS 15.18.2
"If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values."
(这并不明确表示溢出总是给出负数。而且并非总是如此。但是,如果您应用该规则,它确实说明了为什么将Integer.MAX_VALUE递增+1会给您Integer.MIN_VALUE ...)
+1,这很有趣,谢谢让我检查文档!我以前应该做的。谢谢
令人惊讶的是,它不会引起异常。
@theglauber:我不确定它是否令人惊讶。为了引发异常,这意味着每个单独的算术运算都必须伴随着额外的花费在检查溢出上的周期。
一些库具有检查溢出算法的方法,特别是Guavas IntMath和Apaches ArithmeticUtils。
@OliCharlesworth-是的,那就是为什么。但是感觉有点不合Java。例如,出于相同的原因,C不会超出范围检查数组访问,但是Java会进行检查。只是其中之一。提醒您编程语言始终是一系列妥协。
@theglauber-整数溢出和数组越界之间的区别在于,后者可能会破坏内存并在未捕获的情况下破坏JVM。如果未检测到内存践踏,则无法安全地执行(重新定位)GC。
根据文档:
int数据类型是32位带符号的二进制补码整数。最小值为-2,147,483,648(0x80000000),最大值为2,147,483,647(0x7FFFFFFF)(含)
因此,当您将1加到整数的最大值时:
0x7FFFFFFF + 0x00000001 = 0x80000000(-2,147,483,648)
因为当int的值达到Integer.MAX_VALUE时,对其进行递增会导致溢出,因此会回绕到Integer.MIN_VALUE。
要使用较大的整数,请改用64位长的整数。
因为int的范围是-2,147,483,648到2,147,483,647。因此,一旦达到上限,它就会溢出并从负数开始。
参见文档:
int数据类型是32位带符号的二进制补码整数。最小值为-2,147,483,648,最大值为2,147,483,647(含)