目录
前言
在网上看到有网友问补码是谁发明的?最初的作用是什么?回想起刚上大学的时候学习补码,也是一时半会儿适应不过来,对很多问题理解不透彻。如今已经毕业多年,思维早已提升了一个层次,曾经的疑问也早已茅塞顿开。所以借助这个问题,记录一下自己的理解,同时温故知新一下,也希望对初学者有帮助
补码是谁发明的我不知道,但我想补码最初的作用是让计算机实现减法运算吧
一、问题的引入
起初,计算机是没有减法运算的,只能累加
但是天才般的科学家想到一个绝妙的办法,把减法转变成加法来算
灵感来源于时钟,比如,从6点怎么调到5点?你可以逆时针拨动时针一格,就是6-1=5
但你也可以顺时针拨动时针11格,6+11=17,也是5点(超过的12自动舍弃,17-12=5)
现在试想一个4位计数器,初始值是0101,如何清零?
法一:
人类思维,直接减去0101即可,但机器无法直接实现
法二:
Step1: 加上1010,得到1111(计数器已满)
Step2: 再+1得到10000(溢出)
Step3: 第5位多出来的1自动丢失,得到0000
二、反码
重点关注法二,在Step1中,加上的“1010”即反码
注意到反码和原码相加,得到每一位都是1的数“1111”
于是,模仿数学中“相反数”的定义,我们也可以试着给出“反码”的定义:
在一个n位计数器中,若x+y=111…(n个1),则称x和y互为反码
直观上看就是每一位取反即可(0换成1,1换成0)
三、补码
而在加了反码的基础上,再+1,就能使得计数器溢出,溢出部分自然丢失就达到了清零的效果
如果我们把最后两部合并为一步,直接对原码加上“反码+1”,那么将计数器清零就一步到位了
我们把这个“反码+1”称为原码的补码
Tips:补码和原码相加,可以使得计数器正好溢出(或者叫“清零”),我们将这个刚好溢出的值10000称为计数器的模
对时钟来说,时钟的模就是12,但我们知道12点其实就是0点,指针指向同一个刻度;同样地,对计数器来说,10000就是0000
四、二进制减法
下面考虑0101-0011
按照人类正常思维,将计数器往回调0011即可,但遗憾的是计数器没有往回调的功能,我们只能往上加
回想时钟,从6点到5点,可以减1,也可以加11,而加上的1和减去的11相加,刚好等于一个模
同样地,假设0101-0011=y,如果要把0101调到y这个位置,可以选择减去0011,也选择可以加上一个x,而这个x跟0011相加应该刚好等于这个4位计数器的模,那么x即为0011的补码
于是我们得到一条重要的结论:在计数器中,减去一个二进制数,等于加上这个数的补码