一、引入
补码,常常使初学者难以理解,今天我们来解释一下。
首先,出现了一个解决方案,一定是因为出现了一个问题,那么是什么问题呢?
——>原码的加减运算出现了问题。
以四位为例:[2]原=0010,[-3]原=1011,那么2+(-3)就是0010+1011,运算结果是1101,就是-5。这显然不对,错误的原因就是,我们将第一位作为了符号位。
补码作为这个问题的解决方案,就被提了出来。
二、补码的产生
当我们逆向思考的时候,问题往往迎刃而解。
举例:4-3=1,[4]原=0100,[1]原=0001,那么0100加上什么等于0001呢?这个问题显然没有答案,因为无论怎么加0100都不可能变小,除非——舍去最高位,即0100加什么等于1 0001,答案显然是1101。
这里去掉最高位的操作就是相当于在10进制中取了16的模,由于计算机去掉最高位的操作非常简便,我们于是规定用1101作为-3使用,将1101叫做补码。
三、理论基础
我们发现,1101用二进制来理解,就是13,也就是-3在模是16下的模。
这么巧么?我们可不可以这样来理解,第一位先暂时不作为符号位,就是单纯的二进制,将-1~-8都取模,变成了15~8,这样用二进制来加减,得到的结果再用二进制来理解(即得到了1111,理解成-1),我们只是将负数通过取模的方式来进行二进制的加减,最后再取模回来理解,这样下来,好像就实现了加减的功能!
请注意,上面的描述暂时抛弃的原码的符号位概念。
然后我们来看,所有的负数转换了之后,第一位都是1,正数不变,第一位都是0,所以我们就可以规定第一位为1的是负数,为0的是正数。
然后我们又规定,用这样计算方式的数,就是补码。
举例:再回到2-3,①将-3转换成1101,即0010+1101=1111。②1111再转换一下,就是-1。
①的转换是为了计算,②的转换是为了理解补码的正确性。
四、带来的问题
1.我们发现,这样下来,正数加0有8个(0~7),负数有8个(-1~-8)。但是,8就无法表示了。于是负数就比正数多一个。
2.原码里面存在负0和正0,但是补码只有一个0。
五、为什么难以理解
原码是人为的一个规定,而补码是根据问题而提出的解决方案,具有一种天然性,对于补码的种种定义都是后期人为的规定,限制了人们的理解。