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