补码的计算方法
1、二进制补码的计算方法
二进制的补码计算非常简单,各种教材中也经常使用二进制来说明源码、反码与补码三者的关系,掌握一定基础的人都知道一下规则:
1.1 原码
最高位为符号位,0表示正数,1表示负数。
例如:
X = 0b11 (3),四比特表示原码 = 0011(3) ;
X = - 0b11(-3) ,四比特表示原码 = 1011(11) ;
1.2 反码
最高位为符号位,0表示正数,1表示负数。
正数的反码等于本身,负数的反码除符号位外,各位取反:
例如:
X = 0b11 (3),四比特表示原码 = 0011(3),对应反码为 = 0011(3) ;
X = - 0b11(-3) ,四比特表示原码 = 1011(11),对应反码为 = 1100(12) ;
1.3 补码
最高位为符号位,0表示正数,1表示负数。
正数的补码等于本身,负数的补码等于反码+1:
例如:
X = 0b11 (3),四比特表示原码 = 0011(3),对应反码为 = 0011(3) ,补码为 = 0011(3);
X = - 0b11(-3) ,四比特表示原码 = 1011(11),对应反码为 = 1100(12),补码为1101(13) ;
2、十进制的补码计算方法
对于十进制数来说,通过前面的性质不难得到正十进制数补码等于其本身,对于负十进制数来说如果还按位进行运算就太麻烦了!为了讲明白,我们从补码的起因说起:
“反码加一”只是补码所具有的一个性质,不能被定义成补码。负数的补码,是能够和其相反数相加通过溢出从而使计算机内计算结果变为0的二进制码。这是补码设计的初衷,具体目标就是让1+(-1)=0,这利用原码是无法得到的:
0001
(
1
)
+
1001
(
−
1
)
=
1010
(
−
2
)
0001(1)+1001(-1)=1010(-2)
0001(1)+1001(−1)=1010(−2)
而在补码中:
0001
(
1
补
)
+
1110
(
−
1
补
)
=
10000
(
1
溢
出
)
0001(1补)+1110(-1补)=1 0000(1溢出)
0001(1补)+1110(−1补)=10000(1溢出)
所以对于一个n位的负数-X,有如下关系:
X
补
+
(
−
X
)
补
=
1
00
⋅
⋅
⋅
0
⏟
n
=
2
n
X_补+(-X)_补=1 \underbrace{00···0}_n=2^n
X补+(−X)补=1n
00⋅⋅⋅0=2n
所以假设寄存器是n位的,那么-X的补码,应该是
2
n
−
X
2^n-X
2n−X的二进制编码。
例如前面举得例子:
例如:
X = - 0b11(-3) ,四比特表示原码 = 1011(11),对应反码为 = 1100(12),补码为1101(13) ;
如果寄存器4位,-3对应的补码二进制数为13,刚好是 2 4 − 3 2^4-3 24−3
正十进制数补码等于其本身,n位寄存器下-X的补码等于 2 n − X 2^n-X 2n−X对应的二进制编码。
如果使用python的话,可以使用&来快速获取补码:
-3&0xf
Out[1]: 13
5&0xf
Out[2]: 5
这里的0xf指的是0b1111,表示4位的寄存器。如果是7位寄存器,0b111111就是0x3f。
3、已知补码怎么求原码?
对于正数来说,根据前面的介绍很容易知道 原码=补码=反码,接下来主要讨论给定负数的补码怎么求负数的原码:
3.1 二进制
先说结论:补码的补码就是原码。下面开始证明:
已知二进制的补码为
X
补
X_补
X补,根据1.3中求补码的过程易得
X
=
(
X
补
−
1
)
反
X=(X_补-1)_反
X=(X补−1)反
事实上上式还等价于:
X
=
(
X
补
)
反
+
1
X=(X_补)_反+1
X=(X补)反+1
可以简单证明一下,根据反码实际的求解过程可以得到下面式子:
a
+
a
反
=
0
b
11
⋅
⋅
⋅
1
⏟
n
=
2
n
+
1
−
1
=
F
a+a_反=0b \underbrace{11···1}_n=2^{n+1}-1=F
a+a反=0bn
11⋅⋅⋅1=2n+1−1=F
a 反 + 1 = F − a + 1 a_反+1=F-a+1 a反+1=F−a+1
当a=a-1时有:
(
a
−
1
)
反
=
F
−
(
a
−
1
)
(a-1)_反=F-(a-1)
(a−1)反=F−(a−1)
上面两式子说明了:
(
a
−
1
)
反
=
a
反
+
1
(a-1)_反=a_反+1
(a−1)反=a反+1
用文字描述即:取反加一等价于减一取反!
所以二进制补码有如下关系:
X
=
(
X
补
−
1
)
反
=
(
X
补
)
反
+
1
=
(
X
补
)
补
X=(X_补-1)_反=(X_补)_反+1=(X_补)_补
X=(X补−1)反=(X补)反+1=(X补)补
也就是说补码的补码就是原码,有点负负得正的意思哦。
3.1 十进制
n位寄存器下-X的补码等于 2 n − X 2^n-X 2n−X对应的二进制编码。
(1)十进制的情况下,如果给的补码是无符号数 2 n − X 2^n-X 2n−X,那么原码即 ( 2 n − X ) − 2 n = − X (2^n-X)-2^n=-X (2n−X)−2n=−X即可。
例如前面-3补码无符号数是13,对应的原码就是 13 − 2 4 = − 3 13-2^4=-3 13−24=−3
(2)十进制的情况下,如果给的补码是有符号数-Y,对应的无符号数就是 2 n − 1 + Y 2^{n-1}+Y 2n−1+Y,那么原码就是 ( 2 n − 1 + Y ) − 2 n = Y − 2 n − 1 (2^{n-1}+Y)-2^n=Y-2^{n-1} (2n−1+Y)−2n=Y−2n−1。
例如前面-3补码有符号数是-5,对应的原码就是 5 − 2 3 = − 3 5-2^3=-3 5−23=−3