新手问一个关于整数溢出的问题

public class Test {
public static void main(String[] args) {
int integer = 2147483647 + 2;
System.out.println(integer);
}
}

请问为什么整数溢出后输出结果是-2147483647?

你还可以用时钟的方式来理解,假设一个时钟上有如下刻度
-2147483648 --2147483647 -2147483646 -2147483645 ... -3 -2 -1 0 1 2 3 4 ... 2147483645 2147483646 2147483647 (后面接上 -2147483648,转一圈回来)
把这些数字构成一个圆环
加法就是往顺时针拨,减法就是往逆时针拨。
你从2147483647 加2,就是往后拨2格,因为是一个圆环,所以是--2147483647

因为负数的表示方式是,二进制第一位为1,后面取补码。
所以2147483647是二进制01111.....1(31个1)
+2以后是
1000...01(中间30个0)
也就是补码是000...0001,对应的值就是-2147483647

图片说明
这是一个4位数补码图,int型算法可以参考这个图
你可以把它当做是一个圆,一分为2,一半为正数(二进制第一位为0),一半为负数(二进制第一位为1)

先看个例子,,(java的整形是int为4字节(4*8=32位),也是有符号数,-2 147 483 648 ~ 2 147 483 647)

  public static void main(String[] args) {
        int i = 2147483647;
        System.out.println(i);
        System.out.println(i + 1);//-2147483648
        System.out.println(i + 2);//2147483647
        System.out.println(Integer.MAX_VALUE);//2147483647
        System.out.println(Integer.MIN_VALUE);//-2147483648
                System.out.println(0b10000000000000000000000000000000);//-2147483648
    }

整形32位太多了,,以8位为例,,简单说一下(一个道理)

【1】0000 0000 = 0,,,,,首位位0表示正数。
【2】1000 0000 = -0?,错,,负数需要【变反+1,加符号】,,1000 0000变反0111 1111=127,加一等于128,所以【1000 0000】换成有符号数是-128。
(为什么要加以,,因为有个0是正还是负的问题,,最终,把0放到了正数里面【就是0的首位为0】)
【3】0111 1111 = 127,,,,127+1=128?错,,等于-128
0111 1111+1 = 1000 0000 等于【2】中所说的-128

类比一下,,不知道题主懂了没,,,没懂再看看这句代码(1后面31个0,多了编译器都看不下去了(●'◡'●))

    System.out.println(0b10000000000000000000000000000000);//-2147483648

我才知道,原来这个问题还有这么多种解答方法 Orz

数据是要存储在字节里的,而不同数据类型拥有的字节数是固定的。比如 int 整数一般是32位也就是4个字节。想象一下,这四个字节就如同一个杯子,而这个整数的大小就像往里面装的水的多少,水太多了(整数太大)就溢出了嘛!至于溢出的结果实际上不必花心思理解透(实际上如果了解关于字节的基础知识的话,这个问题是很好理解的)。最重要的是编程时注意选择匹配的数据类型。

把一个一维数轴的两端连起来形成一个圆。。。。

int的范围是-2147483648-2147483647,相当于一个环,2147483647再往后两个数就是-2147483647

这是一维数轴的两端连起来形成一个圆,int的范围是-2147483648-2147483647,...2147483646、2147483647、-2147483648、-2147483647、-2147483646...所以结果就是你看到的这样

前面的解答已经很详细了

图片说明