首先区分两个概念:真值与机器码
- 真值:一般书写的数
- 机器码:机器中表示的数
为了解决在计算机内部数的正、负符号和小数点运算问题,而产生了把符号位和数值位一起编码来表示相应的数的表示方法,如原码,反码,补码,移码
1.原码
- 表示方法:
符号位 + 二进制数的绝对值
- 符号位:0为正,1为负,有+0与-0之分
正数:0+二进制数
负数:1+二进制数
- 特点:表示简单,易于同真值之间进行转换,实现乘除运算规则简单。但进行减运算十分麻烦
- 例子:3的二进制数是11,则+3的原码是011,-3的原码是111
- 使用原码做减法(1−1=01−1=0)
1−1=1+(−1)=[00000001]原+[10000001]原=[10000010]原=−21−1=1+(−1)=[00000001]原+[10000001]原=[10000010]原=−2
结果错误
2.反码
- 表示方法:
正数的表示与原、补码相同. 负数的反码符号位为1,数值位是将原码的数值按位取反,就得到该数的反码表示。
- 符号位:0为正,1为负,有+0与-0之分
正数:0+二进制数
负数:1+二进制数按位取反
- 特点:为求补码提供便利
- 例子:3的二进制数是11,则+3的反码是011,-3的反码是100
- 使用反码做减法(1−1=01−1=0)
1−1=1+(−1)=[00000001]原+[10000001]原=[00000001]反+[11111110]反=[11111111]反=[10000000]原=−01−1=1+(−1)=[00000001]原+[10000001]原=[00000001]反+[11111110]反=[11111111]反=[10000000]原=−0
结果正确,但出现了-0,这里的-0和+0是没有区别的,所以在这里让0带符号是没有意义的(数学上有时候需要带符号的0,但这里确实不需要,而且会使得对于同一个数有两种编码方式)
3.补码
- 表示方法:
正数的补码符号位为0 ,尾数与原码相同. 负数的补码符号位为1,数值位是将原码的数值按位取反,再在末位加1
- 符号位:0为正,1为负,无+0与-0之分
正数:0+二进制数
负数:1+(二进制数按位取反,末位+1)
- 特点:将减法转化为加法
- 例子:3的二进制数是11,则+3的补码是011,-3的补码是101
- 使用补码做减法
- 1−1=01−1=0
1−1=1+(−1)=[00000001]原+[10000001]原=[00000001]补+[11111111]补=[00000000]补=[00000000]原1−1=1+(−1)=[00000001]原+[10000001]原=[00000001]补+[11111111]补=[00000000]补=[00000000]原
结果正确,且没有出现-0,这里是正负相加的结果,那如果是通过正正相加或者负负相加得到[10000000]补[10000000]补,又意味着什么呢? - 正正相加:(27−1)+1=12827−1)+1=128
正溢
(27−1)+1==[01111111]原+[00000001]原=[01111111]补+[00000001]补=[10000000]补=[10000000]原(27−1)+1==[01111111]原+[00000001]原=[01111111]补+[00000001]补=[10000000]补=[10000000]原
这里可以看到,用补码时,[10000000]原[10000000]原表示上溢的结果 - 负负相加:−26+(−26)=−128−26+(−26)=−128
负溢
−26+(−26)==[11000000]原+[11000000]原=[11000000]补+[11000000]补=[10000000]补=[10000000]原−26+(−26)==[11000000]原+[11000000]原=[11000000]补+[11000000]补=[10000000]补=[10000000]原
这里可以看到,用补码时,[10000000]原[10000000]原也可以表示下溢的结果
- 1−1=01−1=0
在定点整数机器中,数的表示范围为|x|<(2n−1)|x|<(2n−1),但n位二进制补码数的表示范围是−2n−1−2n−1到2n−1−12n−1−1,
其中用[10000000]原[10000000]原来表示−2n−1−2n−1,这样不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].
但是,同时要注意,用补码表示的−2n−1−2n−1是没有对应的反码和原码的,因为实际上是使用以前的-0的补码来表示-128
4.移码
- 表示方法:
移码和补码尾数相同,符号位相反
- 符号位:1为正,0为负(注意,移码的符号表示与其他三种都不一样)
正数:1+二进制数
负数:0+(二进制数按位取反,末位+1)
- 特点:通常用于表示浮点数的阶码
- 例子:3的二进制数是11,则+3的移码是111,-3的移码是001
比较
表示方法 | 正数 | 负数 | +1011111 | -1011111 |
---|---|---|---|---|
原码 | 0+二进制数 | 1+二进制数 | 01011111 | 11011111 |
反码 | 0+二进制数 | 1+二进制数按位取反 | 01011111 | 10100000 |
补码 | 0+二进制数 | 1+(二进制数按位取反,末位+1) | 01011111 | 10100001 |
移码 | 1+二进制数 | 0+(二进制数按位取反,末位+1) | 11011111 | 00100001 |