相信大家应该或多或少的都了解过原码、反码、补码吧。
原码:原码就是早期用来表示数字的一种方式: 一个正数,转换为二进制位就是这个正数的原码。负数的绝对值转换成二进制位然后在高位补1就是这个负数的原码。
反码:正数的反码就是原码,负数的反码等于原码除符号位以外所有的位取反。
补码:正数的补码与原码相同,负数的补码为 其原码除符号位外所有位取反(得到反码了),然后最低位加1。
————————————————————————————————————————————————————————
这些理解起来并不难,但是,大家有没有想过,已经有原码了,为什么要有反码、补码这两个东西?再一个,为什么补码是反码+1运算得到的?
给大家举个例子。
一个时钟,如果要从9点走到4点,需要怎么走?
第一种可以逆时针往回走5个小时,第二种可以接着顺时针走7个小时。
这个结果大家数数手指头就能算出来,但其实,也可以用表达式计算出来。
首先,我们要知道,时钟的周期是12个小时,每超过12小时,就会归零。那么,顺时针走的话,分两个阶段,一个是走3个小时到12点,这个时候就已经需要重置了,然后在走4个小时,就到了4点这个时刻。
我们可以姑且把3认为是9的补码,因为9 + 3 = 12,而12就是时钟的周期。
现在,我们可以把表达式给计算出来,
4 + (12 - 9)------> 目标时间 + (周期 - 起始时间)
比如11点到9点
第一种是直接11 + (-9) = 2,逆时针往回走2小时,
第二种是9 + (12 - 11) = 10,顺时针再走10个小时。
————————————————————————————————————————————————————————
现在,我们再来看看二进制中负数的反码和补码(因为正数的反码、补码都是本身,所以没必要看)。
比如 -5,首先我们不考虑符号位,-5的绝对值是5,5的二进制是 0 1 0 1,然后将0 1 0 1逐位取反得到 1 0 1 0,
现在我们用 0 1 0 1 + 1 0 1 0 = 1 1 1 1,1 1 1 1 转成十进制就是15,而15 + 1就是4位二进制的周期16,
所以我们需要再反码的基础上+1,才能得到周期数,也就是说反码+1,就是补码。
————————————————————————————————————————————————————————
下面我们再来看下,为什么需要补码,这个东西。
我们要知道,计算机只认识二进制,也根本不认识加减乘除运算,他能做的,只有与、或、异或、取反、左移、右移这几种运算,不熟悉的可以看我的这篇文章https://blog.youkuaiyun.com/qq_32069155/article/details/92441430。
首先,我们来看下9 - 5在计算机中是怎样运算的。
假设我们没有反码、补码,只有原码。那么我们先直接用9的二进制位0 0 0 0 1 0 0 1 加上 -5的二进制位 1 0 0 0 0 1 0 1看看能不能得到结果。
0 0 0 0 1 0 0 1
1 0 0 0 0 1 0 1
异或--------------------
1 0 0 0 1 1 1 0
,
0 0 0 0 1 0 0 1
1 0 0 0 0 1 0 1
与--------------------
0 0 0 0 0 0 0 1
,
发现存在进位,则将与运算结果左移一位,得到 0 0 0 0 0 0 1 0,然后将上次异或结果和左移结果再进行异或运算
1 0 0 0 1 1 1 0
0 0 0 0 0 0 1 0
异或--------------------
1 0 0 0 1 1 0 0
,
1 0 0 0 1 1 1 0
0 0 0 0 0 0 1 0
与--------------------
0 0 0 0 0 0 1 0
,
发现存在进位,则将与运算结果左移一位,得到 0 0 0 0 0 1 0 0,然后将上次异或结果和左移结果再进行异或运算
1 0 0 0 1 1 0 0
0 0 0 0 0 1 0 0
异或--------------------
1 0 0 0 1 0 0 0
,
1 0 0 0 1 1 0 0
0 0 0 0 0 1 0 0
与--------------------
0 0 0 0 0 1 0 0
,
发现存在进位,则将与运算结果左移一位,得到 0 0 0 0 1 0 0 0,然后将上次异或结果和左移结果再进行异或运算
1 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0
异或--------------------
1 0 0 0 0 0 0 0
,
1 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0
与--------------------
0 0 0 0 1 0 0 0
,
发现存在进位,则将与运算结果左移一位,得到 0 0 0 1 0 0 0 0,然后将上次异或结果和左移结果再进行异或运算
1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
异或--------------------
1 0 0 1 0 0 0 0
,
1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
与--------------------
0 0 0 0 0 0 0 0
,
发现不存在进位,则上次异或结果 1 0 0 1 0 0 0 0就是最终结果,也就是 -16。
是不是发现,跟直接9 - 5 的结果完全不一样?也就是说计算机不能直接加上负数的原码,也就是时钟问题中,不能直接减去多少小时,来达到目的时间。那么,在时钟问题中,除了直接减,还有一种加上补码的方式去计算,我们可以来试下。
还是9 - 5,现在我们用9的二进制 0 0 0 0 1 0 0 1 加上-5 的补码 1 1 1 1 1 0 1 1
0 0 0 0 1 0 0 1
1 1 1 1 1 0 1 1
异或--------------------
1 1 1 1 0 0 1 0
,
0 0 0 0 1 0 0 1
1 1 1 1 1 0 1 1
与--------------------
0 0 0 0 1 0 0 1
,
发现存在进位,则将与运算结果左移一位,得到 0 0 0 1 0 0 1 0,然后将上次异或结果和左移结果再进行异或运算
1 1 1 1 0 0 1 0
0 0 0 1 0 0 1 0
异或--------------------
1 1 1 0 0 0 0 0
,
1 1 1 1 0 0 1 0
0 0 0 1 0 0 1 0
与--------------------
0 0 0 1 0 0 1 0
,
发现存在进位,则将与运算结果左移一位,得到 0 0 1 0 0 1 0 0,然后将上次异或结果和左移结果再进行异或运算
1 1 1 0 0 0 0 0
0 0 1 0 0 1 0 0
异或--------------------
1 1 0 0 0 1 0 0
,
1 1 1 0 0 0 0 0
0 0 1 0 0 1 0 0
与--------------------
0 0 1 0 0 0 0 0
,
发现存在进位,则将与运算结果左移一位,得到 0 1 0 0 0 0 0 0,然后将上次异或结果和左移结果再进行异或运算
1 1 0 0 0 1 0 0
0 1 0 0 0 0 0 0
异或--------------------
1 0 0 0 0 1 0 0
,
1 1 0 0 0 1 0 0
0 1 0 0 0 0 0 0
与--------------------
0 1 0 0 0 0 0 0
,
发现存在进位,则将与运算结果左移一位,得到 1 0 0 0 0 0 0 0,然后将上次异或结果和左移结果再进行异或运算
1 0 0 0 0 1 0 0
1 0 0 0 0 0 0 0
异或--------------------
0 0 0 0 0 1 0 0
,
1 0 0 0 0 1 0 0
1 0 0 0 0 0 0 0
与--------------------
1 0 0 0 0 0 0 0
,
发现存在进位,则将与运算结果左移一位,得到 0 0 0 0 0 0 0 0,然后将上次异或结果和左移结果再进行异或运算
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0
异或--------------------
0 0 0 0 0 1 0 0
,
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0
与--------------------
0 0 0 0 0 0 0 0
,
发现不存在进位,则上次异或结果 0 0 0 0 0 1 0 0就是最终结果,也就是 4。
所以,可以得出结论,计算机可以直接加上其被减数的补码,来达到运算减法的问题,也就是说,补码,其实就是为了更方便的减法运算,他可以使得负数能够使用加法器参与加法运算。
总结下:反码、补码之所以存在是为了是负数能直接参与加法运算,计算机只用实现加法,就能达到实现加减乘除。
补码 = 反码 + 1是因为原码 + 反码 = 1 1 1 1,也就是当前容量的最大数,但是,只有再加一,才会等于周期数,然后我们上面了解到,补码加上原码会等于周期数,所以补码 = 反码 + 1。
自此,本文结束,上述内容是参考了https://blog.youkuaiyun.com/zhuozuozhi/article/details/80896838之后,本人所做的一些总结和补充,如果什么不足,还请指正。
PS:本文中,还有一个坑,大家可以找找看。 = =。
本文介绍了原码、反码、补码的概念,通过时钟例子解释补码原理。以二进制运算展示,仅用原码计算减法结果错误,而用补码可正确运算。指出反码、补码存在是为让负数参与加法运算,补码等于反码加1是为使原码与补码和为周期数。
1483

被折叠的 条评论
为什么被折叠?



