首页 > 代码库 > 一张图看懂原码、反码、补码、移码

一张图看懂原码、反码、补码、移码

前言  

  原码、反码、补码其实两年前就讲过,只是当时的理解太过肤浅或者直接说就是没有理解,因为对于数学比较发怵的我看到那么多的公式很是脑袋大,所以想要硬记也记不住。这次讲课的时候好歹知道了运算规则,但别人一问为什么,立马那个冏啊~好了,废话不多说了,开始进入正题(如果我的理解有偏差,恳请各位大虾不吝指出):

    一张图胜过千言万语,下面的这张是本篇想要说的大概内容

                                                                       

原码

    我们知道,计算机是以0和1进行运算的,而且内部只有加法运算器,但日常生活中使用的却是十进制,并且有正负之分。于是我们发明了原码:最高位存放符号(正数用0表示,负数用1表示),其余为真值位。这样就可以方便的进行算术运算了。但很快,我们发现在进行加、乘、除的时候结果均正确,减法却出现了一些问题,下面举个例子:

假设计算机的字长为8 byte,那么

                   (2)-(2)D = (2)D +(-2)D = (0)D   D表示十进制

                   (00000010)+(10000010)=(10000100)=(-4)D

反码

    以上结果用原码进行计算的显然不正确。因为正数计算的时候没有问题,那么肯定出现在负数身上,为了解决这个问题,我们引入了反码:对负数的原码符号位不变,真值位进行逐位取反。反码的运算如下:

                (1)D-(2)D=(-1)D
                (00000001)+(11111101)=(11111110)=(10000001)=(-1)D

    而对于在原码中提到的十进制2-2=0的算法如下:

            (00000010)+(11111101)=(11111111)=(10000000)=(-0)D

补码

         发现得到的结果是-0!而在我们的日常计算中,0是不分正负的。为了解决这个问题,我们引入了补码:对负数的补码真值位加1。如果最高位(符号位)有进位,则进位被舍弃。

         在补码中用(-128)D代替了(-0),故补码的表示范围为(-128~0~127)共256个。需要注意的是:(-128)D没有对应的原码和反码。补码的十进制2-2=0的运算如下:

            (00000010)+(11111110)=(00000000)=(00000000)=(0)D

         可以发现补码的运算无误(大家感兴趣的话可以使用其他式子练习),因此,在计算机系统中,数值一律使用补码进行存储,它能将符号位和真值位统一进行处理。

移码

         但是我们不能高兴的太早,还有一个问题:大家有没有发现(-2)D的原码、反码、补码分别大于(2)D的原码、反码、补码?这跟我们日常的认知不相符,为了解决这个问题,我们引入了移码的概念(其实这个并不是移码的来历,只是为了好记一些而已):如果机器字长为n,规定数X上增加一个偏移量2n-1。那么,这个时候

                [-2]=27+(-2)D =(1000000)+(11111110)=(01111110)

                [2]=27+(2)=(10000000)+(00000010)=(10000010)

                [-2]<[2]

结语

    终于把我要说的说完了,虽然费了不少的劲去整明白来龙去脉,但明白了原理之后再进行计算就相当容易了。以后的学习中也应该去养成这个习惯,知其然知其所以然,多问几个为什么,当不知道答案的时候说明肯定对这部分的知识还没有掌握到位。接下来,努力吧,少年!