二进制、反码、补码
前置阅读:
基础概念
有符号二进制整数有正数和负数。在 x86 处理器中,MSB 表示的是符号位:0 表示正数,1 表示负数。下图展示了 8 位的正数和负数:
概念总结:
- 反码、补码是二进制的一种表现形式;
- 在计算机内所有数值底层都用补码表示,无论正负数(十进制);
- 如果一串二进制值需要视为数值则需要将其视为补码;
- 反码是十进制转二进制计算的一个过程即对一个十进制取补码的过程,一般用在负数转换规则上;
- 反码可以通过二进制值按位取反得到(所有二进制位都取反);
- 正数(十进制)的补码是其二进制本身,负数(十进制)的补码是十进制负数的绝对值求补码后取反码加一;
表示正数的补码可以直接转成十进制,表示负数的补码想要转回十进制
~~步骤如~~下:- 对表示负数的补码取反码加一得到负数的十进制绝对值补码;
- 再将负数的十进制绝对值补码转成十进制得到负数的十进制绝对值;
- 最后加上符号位;
- 无论是正数加正数(十进制加法)还是正数/负数加负数(十进制减法)都可以用补码加补码表示;
- 一个值的正数的补码与其负数的补码相加等于 0;
反码
反码可以通过二进制值按位取反得到(所有二进制位都取反)
正数的反码示例:
十进制数值 | 补码 | 反码 |
---|---|---|
0 | 0000 0000 | 1111 1111 |
1 | 0000 0001 | 1111 1110 |
2 | 0000 0010 | 1111 1101 |
3 | 0000 0011 | 1111 1100 |
4 | 0000 0100 | 1111 1011 |
负数的反码示例:
十进制数值 | 补码 | 反码 |
---|---|---|
-0 | 0000 0000 | 1111 1111 |
-1 | 1111 1111 | 0000 0000 |
-2 | 1111 1110 | 0000 0001 |
-3 | 1111 1101 | 0000 0010 |
补码(十进制转二进制)
在计算机内所有数值底层都用补码表示,无论正负数(十进制)
十进制数值 | 补码 |
---|---|
0 | 0000 0000 |
1 | 0000 0001 |
2 | 0000 0010 |
3 | 0000 0011 |
-0 | 0000 0000 |
-1 | 1111 1111 |
-2 | 1111 1110 |
-3 | 1111 1101 |
负数补码计算过程示例:
十进制数值 | 绝对值 | 绝对值补码 | 绝对值补码取反 | 绝对值补码取反加一 | 正确补码 | 十进制数值 |
---|---|---|---|---|---|---|
-0 | 0 | 0000 0000 | 1111 1111 | 1111 1111 + 1 ————— 1,0000 0000 | 0000 0000 | -0 |
-1 | 1 | 0000 0001 | 1111 1110 | 1111 1110 + 1 ————— 1111 1111 | 1111 1111 | -1 |
-2 | 2 | 0000 0010 | 1111 1101 | 1111 1101 + 1 ————— 1111 1110 | 1111 1110 | -2 |
-3 | 3 | 0000 0011 | 1111 1100 | 1111 1100 + 1 ————— 1111 1101 | 1111 1101 | -3 |
-4 | 4 | 0000 0100 | 1111 1011 | 1111 1011 + 1 ————— 1111 1100 | 1111 1100 | -4 |
-5 | 5 | 0000 0101 | 1111 1010 | 1111 1010 + 1 ————— 1111 1011 | 1111 1011 | -5 |
补码(二进制转十进制)
表示正数的补码可以直接转成十进制,表示负数的补码想要转回十进制步骤如下:
- 对表示负数的补码取反码加一得到负数的十进制绝对值补码;
- 再将负数的十进制绝对值补码转成十进制得到负数的十进制绝对值;
- 最后加上符号位;
MSB | 补码 | 十进制数值 |
---|---|---|
0 | 0000 0000 | 0 |
0 | 0000 0001 | 1 |
0 | 0000 0010 | 2 |
0 | 0000 0011 | 3 |
0 | 0000 0100 | 4 |
0 | 0000 0101 | 5 |
1 | 1111 1111 | -1 |
1 | 1111 1110 | -2 |
1 | 1111 1101 | -3 |
1 | 1111 1100 | -4 |
1 | 1111 1011 | -5 |
负数转换示例:
MSB | 补码 | 补码取反 | 补码取反加一 | 补码取反加一后所代表十进制值 | 符号 | 十进制结果 | 补码 |
---|---|---|---|---|---|---|---|
1 | 1111 1111 | 0000 0000 | 0000 0001 | 1 | - | -1 | 1111 1111 |
1 | 1111 1110 | 0000 0001 | 0000 0010 | 2 | - | -2 | 1111 1110 |
1 | 1111 1101 | 0000 0010 | 0000 0011 | 3 | - | -3 | 1111 1101 |
1 | 1111 1100 | 0000 0011 | 0000 0100 | 4 | - | -4 | 1111 1100 |
1 | 1111 1011 | 0000 0100 | 0000 0101 | 5 | - | -5 | 1111 1011 |
补码相加
无论是正数加正数(十进制加法)还是正数/负数加负数(十进制减法)都可以用补码加补码表示
正数加正数的补码计算过程示例:
表达式 | 补码相加 | 二进制结果 | 十进制结果 |
---|---|---|---|
0+0 | 0000 0000 + 0000 0000 —————— 0000 0000 | 0000 0000 | 0 |
0+1 | 0000 0000 + 0000 0001 —————— 0000 0001 | 0000 0001 | 1 |
1+1 | 0000 0001 + 0000 0001 —————— 0000 0010 | 0000 0010 | 2 |
2+1 | 0000 0010 + 0000 0001 —————— 0000 0011 | 0000 0011 | 3 |
正数加负数的补码计算过程示例:
表达式 | 补码相加 | 二进制结果 | 十进制结果 |
---|---|---|---|
0+(-0) | 0000 0000 + 0000 0000 —————— 0000 0000 | 0000 0000 | 0 |
0+(-1) | 0000 0000 + 1111 1111 —————— 1111 1111 | 1111 1111 | -1 |
1+(-1) | 0000 0001 + 1111 1111 —————— 1,0000 0000 | 0000 0000 | 0 |
1+(-2) | 0000 0001 + 1111 1110 —————— 1111 1111 | 1111 1111 | -1 |
2+(-2) | 0000 0010 + 1111 1110 —————— 1,0000 0000 | 0000 0000 | 0 |
2+(-1) | 0000 0010 + 1111 1111 —————— 1,0000 0001 | 0000 0001 | 1 |
负数加负数的补码计算过程示例:
表达式 | 补码相加 | 二进制结果 | 十进制结果 |
---|---|---|---|
(-0)+(-0) | 0000 0000 + 0000 0000 —————— 0000 0000 | 0000 0000 | 0 |
(-1)+(-1) | 1111 1111 + 1111 1111 —————— 1,1111 1110 | 1111 1110 | -2 |
(-1)+(-2) | 1111 1111 + 1111 1110 —————— 1,1111,1101 | 1111 1101 | -3 |
二进制、反码、补码
同样的一串二进制数字,即可以是反码也可以是补码,如果是补码则其可以通过上述规则转成对应的十进制数值,如果是反码则代表其为计算过程中间值,如果想知道反码在十进制中所表示的数值,可以将其视为补码再通过上述规则转成十进制即可。
正数示例:
十进制数值 x | 取补码 fn1(x)=a | 取反码 fn2(x)=b | 计算反码结果代表的十进制数值 y |
---|---|---|---|
0 | 0000 0000 | 1111 1111 | -1 |
1 | 0000 0001 | 1111 1110 | -2 |
2 | 0000 0010 | 1111 1101 | -3 |
3 | 0000 0011 | 1111 1100 | -4 |
4 | 0000 0100 | 1111 1011 | -5 |
负数示例:
十进制数值 x | 取补码 fn1(x)=a | 取反码 fn2(x)=b | 计算反码结果代表的十进制数值 y |
---|---|---|---|
-0 | 0000 0000 | 1111 1111 | -1 |
-1 | 1111 1111 | 0000 0000 | 0 |
-2 | 1111 1110 | 0000 0001 | 1 |
-3 | 1111 1101 | 0000 0010 | 2 |
示例汇总:
十进制数值 x | 取补码 fn1(x)=a | 取反码 fn2(x)=b | 计算反码结果代表的十进制数值 y |
---|---|---|---|
0 | 0000 0000 | 1111 1111 | -1 |
1 | 0000 0001 | 1111 1110 | -2 |
2 | 0000 0010 | 1111 1101 | -3 |
3 | 0000 0011 | 1111 1100 | -4 |
-0 | 0000 0000 | 1111 1111 | -1 |
-1 | 1111 1111 | 0000 0000 | 0 |
-2 | 1111 1110 | 0000 0001 | 1 |
-3 | 1111 1101 | 0000 0010 | 2 |
通过该表格示例可以得出以下两个规律:
规律 1
反码所表示的数值与原数值之间规律如下(y 代表反码之后的十进制值):
- fn2(x) = -x-1
- fn2(x) + 1 = -x
- y = -x-1
- y +1 = -x
即如果想得到一个十进制正数值的负数形式(1 => -1)或则得到一个十进制负数值的正数形式可以通过对原值取反码加一得到:
十进制数值 x | 十进制取反 -x | 过程 |
---|---|---|
0 | 0 | 取反码(0)+1 = -1+1 |
1 | -1 | 取反码(1)+1 = -2+1 |
2 | -2 | 取反码(2)+1 = -3+1 |
3 | -3 | 取反码(3)+1 = -4+1 |
-1 | 1 | 取反码(-1)+1 = 0+1 |
-2 | 2 | 取反码(-2)+1 = 1+1 |
-3 | 3 | 取反码(-3)+1 = 2+1 |
规律 2
将示例汇总表格再进一步简化:
十进制数值 x | x 的反码十进制表示形式 y | 翻译 -1 | 翻译 -2 |
---|---|---|---|
0 | -1 | 0 的反码是 -1 | -1 是 0 的反码 |
1 | -2 | 1 的反码是 -2 | -2 是 1 的反码 |
2 | -3 | 2 的反码是 -3 | -3 是 2 的反码 |
3 | -4 | 3 的反码是 -4 | -4 是 3 的反码 |
-0 | -1 | -0 的反码是 -1 | -1 是 -0 的反码 |
-1 | 0 | -1 的反码是 0 | 0 是 -1 的反码 |
-2 | 1 | -2 的反码是 1 | 1 是 -2 的反码 |
-3 | 2 | -3 的反码是 2 | 2 是 -3 的反码 |
可以看出在十进制格式下,原数值与反码的关系:
- 如果我需要 -1 我可以用 0 的反码代替;
- 如果我需要 -4 我可以用 3 的反码代替;
规律:
- x = |y| -1
- x + y = -1
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。