无符号整数0-1=2^32-1

```unsigned int a = 0;
cout << a - 1;

输出结果为2^32-1,
  0000 0000 0000 0000 0000 0000 0000 0000
- 0000 0000 0000 0000 0000 0000 0000 0001
怎么就等于
    1111 1111 1111 1111 1111 1111 1111 1111 
    呢?被减数都是0怎么借位?

看看计算机组成原理里的计算机中的数字加减实现,计算机中都是加法,使用补码表示,使用最高位表示正负,

以8位 来举例 说明一下吧,

数字1 内存中保存为 0000 0001
1 + 1 就是
0000 0001
+0000 0001
-----------------
0000 0010

正数的加法很简单 就是这样
但是负数 就比较麻烦
-1 原码表示 为 1000 0001 第一位是符号位
但是这样的话 正数和负数的计算就会遇到麻烦
所以 聪明的大大们 搞出来了 一个叫补码的概念 说到补码就得先说反码,反码就是 除了符号位 所有位取反
那么 -1 的反码就成了 1111 1110
补码呢 就是给反码再加一

所以 -1 的补码就成了 1111 1111
有什么用呢. 看下面,
1-1=0 可以使用下面的方式表示
-1 +1 =0
使用反码的话 就是
0000 0001
+1111 1111
---------------------
1 0000 0000
计算机存储的位数不会变化, 1是第9位 溢出了, 溢出位是会直接丢弃的, 所以巧妙的使用了溢出 来完成了计算机中的加法计算
得到一个正确的结果
0000 0000
即 结果为0

-1的存储就是0xffffffff,
你可以认为,0-1就是10000...000(1后面32个0) - 1=1111...111(32个1)。
这个33位上作为借位的1其实是想象的。

如果你学过数字电路,你就知道,其实计算机内部的加法器、减法器,就是不考虑进位借位的。它们通过计算结束以后设置一个标志位,让更高位实现+/-来进位退位。
这种做法在硬件上是最简单的。

因此我们用补码(反码+1)来表示负数。

负数我们使用补码来表示,最高位表示正负