原码、反码、补码
计算机存储数据是以补码的形式进行存储的
原码
已一个字节(8 位)为例,注意一下的所有演化都是以 8 位一字节为例。
最高位为符号位,0 代表正数,1 代表负数,非符号位为该数字绝对值的二进制
反码
正数的反码与原码一致,负数的反码是对原码按位取反,只是最高位(符号位)不变。
补码
正数的补码与原码一致,负数的补码是该数的反码加一
|
5 |
|
-5 |
| 原码 |
0000 0101 |
|
1000 0101 |
| 反码 |
0000 0101 |
|
1111 1010 |
| 补码 |
0000 0101 |
|
1111 1011 |
1. 计算机存储数据是以补码的形式进行存储的
2. 正数的补码等于它本身
3. 负数的补码等于反码加一
ps:补充,计算机中的计算都是已存储单位补码进行运算的
- 因为计算机中只有加法没有减法,所以需要把减法转为加法,如下:
5 - 5 = 5 + (- 5)
逻辑一:使用原码计算
|
原码 |
原码 |
|
| 5 |
0000 |
0101 |
|
| - 5 |
1000 |
0101 |
|
|
同位数加 |
同位数加 |
|
| 结果是原码 |
1000 |
1010 |
- 10 |
|
|
|
错误 |
逻辑二:使用反码计算
|
反码 |
反码 |
|
| 5 |
0000 |
0101 |
|
| - 5 |
1111 |
1010 |
|
|
同位数加 |
同位数加 |
|
| 结果是反码 |
1111 |
1111 |
|
| 反码转换为原码 |
取反 |
取反 |
|
| 原码 |
1000 |
0000 |
- 0 |
|
|
|
两个不同的进制表示同一个数,矛盾了。因为在计算机的补码机制中,零使用 0000 0000 来表示,1000 0000 就多出来了,设计之初,就设定 1000 0000 会往后顺沿一位,如下表: |
|
0000 |
0000 |
+ 0 |
| 数值 |
原码 |
| 128 |
0000 0000 0000 0000 0000 0000 1000 0000 |
| - 128 |
1000 0000 0000 0000 0000 0000 1000 0000 |
- 以上可以得知:36 位系统中,最高位是符号位,相同数字的原码是一致的,但是计算机 byte 的范围只有 8 位,其中最高位还是符号位,那么剩余的 7 位最大只能是 - 127 ~ + 127,那么就会造成补码 0000 0000 和补码 1000 0000 分别表示 + 0 和 - 0,但是系统只需要一个值来表示 0 就可以了,所以就在 8 位的基础上将 1000 0000 表示的负数往前借一位,这就造成了补码 1000 0000 在计算机中是一个特殊的补码,它没有原码与反码,只以补码的形式存在,如下:
| 数值 |
原码 |
|
|
|
|
36 位 |
|
|
|
| 128 |
0000 0000 |
0000 0000 |
0000 0000 |
1000 0000 |
| - 128 |
1000 0000 |
0000 0000 |
0000 0000 |
1000 0000 |
如果是固定逻辑的话,演化如下:
| 数值 |
补码 |
|
|
|
8 位 |
借位 |
|
| - 128 |
|
0000 0001 |
1000 0000 |
|
反码 |
借位 |
按位取反 |
| - 128 |
|
0000 0001 |
0111 1111 |
|
补码 |
借位 |
反码加一 |
| - 128 |
|
0000 0001 |
1000 0000 |
- 但是系统中值存储只有一字节 8 位,要存储 1 1000 0000 就需要两个字节,在只取低 8 位的情况下,将 1000 0000 特殊处理。
逻辑三:使用补码计算
|
补码 |
补码 |
补码 |
|
| 5 |
|
0000 |
0101 |
|
| - 5 |
|
1111 |
1011 |
|
|
|
同位加 |
同位加 |
|
|
1 |
0000 |
0000 |
|
|
去掉最高位 |
去掉最高位 |
去掉最高位 |
一个字节只有八位,所以去掉最高位 |
|
|
0000 |
0000 |
0 |