什么是原码, 反码, 补码
以-127为例, 在计算机中都是以二进制的方式储存
原码 : 1111 1111
反码: 1000 0000
补码: 1000 0001
原码用来储存正整数, 补码用来储存负数.
想要了解为什么补码 = 反码 + 1 先要知道什么是 '模'
以时钟为例:
例如现在是 11点, 你想让时间回到10点, 那么可以有两种方式:
- 直接往回拨1个小时, 11 - 1 = 10
- 往前拨11个小时, 也能回到10点, 11 + 11 = 10
那么我们可以说时钟这个"计量器"的 "模"就是 12, 也就是到了12之后又会从1重新开始计量, 11 和 1就"互为补数", 类似的4 和 8也是互为补数, 以此类推.
可见, 我们想让时钟回到某个固定的点数
11 - Y = 10
11 + X = 10
即 11 - Y = 11 + X
那么这个X 和 Y 一定要满足的关系就是 X + Y = 模数, 才能使他们计算结果的相等.
计算机中的模数
- 以下讨论都是基于一个字节(即8bit)大小的整数加减运算
一个字节最多表示[0, 255], 一共256个数据, 那么对一个字节来说, "模"是多少呢? 显然是256.
那么如果我要计算 255 - 1, 其实和计算 255 + 255 的结果是一样的. 因为 1 和 255 互为补数. 所以计算机不会储存-1 的原码, 而是储存255的原码(也就是-1的补码)
最后, 为什么 补码 = 反码 + 1
刚才说到要满足255 - 1 = 255 + X,
那么X = 256(模数) - 1 = 255
用二进制表示
1 0000 0000 (256)
- 0000 0001
___________________
= 1111 1111 (255)
由于一个字节最多只能表示 1111 1111 ,所以
1111 1111 (255)
- 0000 0001
___________________
= 1111 1110 (254)
我们可以看到拿八位二进制能表示的最大数字1111 1111 减去 1 之后 刚好结果就是
1本身的二进制代码 0000 0001 按位取反的结果 1111 1110
但是这个结果我们是拿255 去减的, 并不是模数 256去减的, 所以我们还要把结果再加一个1, 才是正确的结果.
所以, 一个负数的补码 = 反码(负数的反码=除符号位之外,按位取反) + 1.