> For the complete documentation index, see [llms.txt](https://jun-wang.gitbook.io/learnjava/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jun-wang.gitbook.io/learnjava/ji-shu-xue-xi/ji-suan-ji-yuan-li/zheng-xing-ji-suan.md).

# 整型计算

今天做LeetCode看到一道题，[翻转整型](https://leetcode.com/problems/reverse-integer/discuss/4060/My-accepted-15-lines-of-code-for-Java)，其中一行代码`if ((newResult - tail) / 10 != result)`表示超出范围就会有损失，有点不太明白，正好之前复习过原码，反码，补码这些，研究了半天，写个总结。接下来从两个问题入门看计算机内部是如何计算的。

## 1. 为什么Integer.MAX\_VALUE + 1 = Integer.MIN\_VALUE

我们可以用java代码测试一下：

```java
System.out.println(Integer.MAX_VALUE + 1);
System.out.println(Integer.MIN_VALUE);

打印：
-2147483648
-2147483648
也就是-2^31
```

我们知道带符号整型的取值范围是 **\[-2^31 \~ 2^31-1]**，在计算机中是以补码的形式存储的，先来复习一下什么是补码，反码和原码：

```
正整数的原码，反码，补码一样，符号位固定为0。
负整数的原码，反码，补码符号位为1：
反码 = 原码各位取反(除第一位符号位)
补码 = 反码 + 1

以-1为例：
原码：10000000，00000000，00000000，00000001
反码：11111111，11111111，11111111，11111110
补码：11111111，11111111，11111111，11111111
计算机内部是使用补码存储并且计算的，那么-1-1的过程就是
-1的补码 11111111，11111111，11111111，11111111 - 1
得到-2的补码：11111111，11111111，11111111，11111110
那么-2的反码：11111111，11111111，11111111，11111101
那么-2的原码：10000000，00000000，00000000，00000010
```

有了这个基础我们来看一下为什么`Integer.MAX_VALUE + 1 = Integer.MIN_VALUE`:

```
Integer.MAX_VALUE的二进制是：
01111111，11111111，11111111，11111111
+1得到
10000000，00000000，00000000，00000000
这是补码，根据补码可以得到反码：
11111111，11111111，11111111，11111111
注意：可能发现10000000，00000000，00000000，00000000 - 1应该是
01111111，11111111，11111111，11111111啊，因为负整数符号位不变，因此符号位由0变为1.
进而得到原码：
10000000，00000000，00000000，00000000
因为00000000，00000000，00000000，00000000已经表示为0了，计算机规定10000000，00000000，00000000，00000000就代表负整数的最小值即Integer.MIN_VALUE。

因此Integer.MIN_VALUE的
补码：10000000，00000000，00000000，00000000
反码：11111111，11111111，11111111，11111111
原码：10000000，00000000，00000000，00000000

接着看一下Integer.MIN_VALUE + 1
补码：10000000，00000000，00000000，00000001
反码：10000000，00000000，00000000，00000000
原码：11111111，11111111，11111111，11111111
```

## 2. 为什么Integer.MAX\_VALUE \* 10 = -10

```
Integer.MAX_VALUE * 10在计算机内部就是10个Integer.MAX_VALUE相加(好像是...)
Integer.MAX_VALUE的二进制为：
01111111，11111111，11111111，11111111
首先看一下Integer.MAX_VALUE * 2就是
01111111，11111111，11111111，11111111 +
01111111，11111111，11111111，11111111 =
11111111，11111111，11111111，11111110(补码)
11111111，11111111，11111111，11111101(反码)
10000000，00000000，00000000，00000010(原码)
所以Integer.MAX_VALUE * 2 = -2
可以使用System.out.println(Integer.MAX_VALUE * 2); 验证一下！

接下来可以一步一步计算出Integer.MAX_VALUE * 10，就是10个Integer.MAX_VALUE相加
最后结果为：
11111111，11111111，11111111，11110110(补码)
11111111，11111111，11111111，11110101(反码)
10000000，00000000，00000000，00001010(原码)
即-10.
```

#### 补充：

为什么计算机内部要用补码进行计算，可以看看这篇文章：

<https://www.cnblogs.com/raytheweak/p/7290617.html>
