@目录
简述
补码是计算机中表示有符号整数的一种方法,它使用了一个特殊的表示法,使得正数和负数的运算可以在硬件上使用相同的加法和逻辑电路来处理。下面我将使用几个例子来说明补码的加法和减法运算规则。
补码加法:
正负
假设我们使用8位补码表示有符号整数,我们有两个数要相加:5 + (-3)
。
将数字转换为二进制表示(原码):
5
的二进制表示:0000 0101
-3
的二进制表示:1000 0011
反码:
5
的反码表示:0000 0101
-3
的反码表示:1111 1100
补码:
5
的补码表示:0000 0101
-3
的补码表示:反码 + 1 = 1111 1100 + 1 = 1111 1101
执行加法运算:
0000 0101
+ 1111 1101
----------
1 0000 0010
1 0000 0010
有进位,舍弃进位1。
所以,补码是0000 0010
表示的是一个正数。首位为0
,表示正号。
正数的:原码 = 补码 = 反码
结果是 2
。
正正
例如,计算 3 + 2
。
转换为二进制表示(原码):
3
的原码表示:0000 0011
2
的原码表示:0000 0010
反码是原码本身。
补码是原码本身。
执行加法运算:
0000 0011
+ 0000 0010
----------
0000 0101
补码0000 0101
表示的是一个正数。首位为0
,表示正号。
正数的:原码 = 补码 = 反码
结果为正数 5
。
负负:
例如,计算 -3 + (-2)
。
转换为二进制表示(源码):
-3
的原码表示:1000 0011
-2
的原码表示:1000 0010
反码:
-3
的反码表示:1111 1100
-2
的反码表示:1111 1101
补码:
-3
的补码表示:反码 + 1 = 1111 1100 + 1 = 1111 1101
-2
的补码表示:反码 + 1 = 1111 1101 + 1 = 1111 1110
执行加法运算:
1111 1101
+ 1111 1110
----------
1 1111 1011
1 1111 1011
有进位,舍弃进位1。
所以,补码是1111 1011
表示的是一个负数。首位为1
,表示负号。
反码 = 补码 - 1 = 1111 1011 - 1 = 1111 1010
故,原码 = 1000 0101
结果是 -5
。
补码减法:
将[x-y]补
转换成[x]补+[-y]补
,即 [x-y]补=[x]补+[-y]补
然后就和上面的补码加法的各种情况类似了。
为什么补码相加,如果有进位则舍弃
补码相加时,如果有进位则舍弃的原因是为了保证运算的正确性和一致性。补码的优点是可以将正数和负数的加法和减法统一处理,而且避免了正零和负零的存在。但是,如果不舍弃进位,就可能出现溢出或错误的结果。
例如,假设我们用7
位二进制数表示有符号整数,那么它的范围是-64到63。如果我们要计算-54-30,那么我们需要先求出-54和-30的补码,然后相加:
-54
的原码是10000110
,补码是11111010
, -30
的原码是10011110
,补码是11100010
两者相加得到11011100
,这个结果的最高位(符号位)为1
,表示结果为负数,需要先求出其原码再转换成十进制。原码是10100100
,十进制是-84
。
这个结果是正确的,因为-54-30
确实等于-84
。但是,如果我们不舍弃进位,就会得到一个错误的结果:
两者相加得到(1)1011100
,这个结果的最高位(符号位)为0
,表示结果为正数,直接转换成十进制就是44
。
这个结果是错误的,因为-54-30
不等于44
。这种情况就叫做溢出了。溢出意味着运算结果超出了能表示的范围。
所以,为了避免溢出或错误的结果,我们需要舍弃进位。舍弃进位并不会影响运算的正确性和一致性,因为补码运算存在符号位进位自然丢失而运算结果正确的规律。
其实我感觉这问题有点类似于1+1=2
是为什么?