关于补码,大概率,你的老师也会这么讲:对于非负数,补码和原码一样,对于负数,符号位为 1,其余位是原码的反码再加 1。
这纯粹是为了让你考试不至于出错,而不是为了更好的理解计算机。可以说这样教的老师都是误人子弟。
直到我看了《深入理解计算机系统》关于补码的知识,才明白遇到一个好的老师或看一本经典的书籍有多么的重要。我尝试以通俗的话展示给你看。
补码的定义
补码的定义,只有这一种:
补码的定义上图中的 x0,x1 表示 0 或 1,w是机器字长,比如对于 w = 8 的情况,补码 11111111 代码的整数含义就是 -1 ,按照定义,其计算过程如下
>>> -2**7 + 2**6 + 2**5 + 2**4 + 2**3 +2**2 +2**1 +2**0
-1
>>>
符号位就是负权重最高的位,-2 的 7 次方,然后逐位按照二进制的计算方法相加,得到结果 -1 。
补码的计算也不需要先计算反码,再加 1,跟原码、反码没有任何关系,是有严格定义的,别听老师强行安利三者之间的关系,搞的补码非常难以理解和计算。对于有符号数,计算机只存储补码,压根不存储反码,更别提再加一的操作了。
为什么会有补码?
第一,补码比原码节省一个二进制位。
如果只用原码,那么因为符号位的存在,会出现 +0 和 -0 的情况,浪费一个二进制位。比如 8 位二进制,原码 00000000 和 10000000 其实都表示 0,因此原码只能表示 -127 到 +127 共 255 个数,实际上 8 为可以表示 2 的 8 次方即 256 个数。 而补码从 10000000 到 01111111 表示 -128 到 +127 表示 256 个数。
第二,补码可以理解为一个环,方便计算减法。
以 8 位为例子,
二进制 [ 00000000, 00000001, 00000010, 00000011 ...
01111111, 10000000, 10000001 ... 11111101, 11111110,11111111]
原码的范围 [0, 1, 2, 3 ... 127, 128, 129 ... 253, 254, 255]
补码的范围 [0, 1, 2, 3 ... 127, -128, -127 ... -3, -2, -1]
这些数,你可以看成收尾相连的环。
比如二进制 11111101 原码表示 253,补码表示 -3 。
比如计算 5 - 3 = 5 + (-3) = 5 + 253 = 258
258 超过了 8 位能表示的范围,怎么半,溢出就行了,怎么溢出,就取模运算即可,就是 258 mod 256 ,说白了就是 258 除以 256 的余数,自然就是 2 了
补码计算减法相当于做了次加法,结果溢出就兜个圈又回来了,完美。
最后
如果你对计算机的基础知识感兴趣,私信我,或加~唯~心,与简书 ID 一致,我给你珍藏的电子书《深入理解计算机系统》。
如果对我的文章感兴趣,欢迎关注我的简书 somenzz,全网唯一 ID。
网友评论