2020-10-12

补码的由来

我们知道,假如进行10进制的14-14,结果等于0,这很容易实现,那么计算机内部是如何处理的呢,我们知道计算机进行加法运算的时候,直接是将原码进行相加即可得到正确的结果,那么14-14直接进行原码的操作会发生什么呢?

将进制进行转化得到

 14D = 00001110B
-14D = 10001110B
  00001110
+ 10001110
-----------
  10011100
10 - 2 = 8;
// 我们需要将时钟拨快10个小时
10+10=20
// 拨快10小时后时间变为了20点,因为时钟一圈的总数是12,所以超过20是没有意义的,那么就要减去12
// 那么此处为什么要取模运算呢,因为可能超过12的数量可以是很多很多圈,例如超过了2个12小时
20/12=8
a 10 - 2 = 8
b (10 + 10) / 12 = 8//实际上,模以12操作,是自然进行的,我们并没有去进行此项操作
B 10 + 10 = 8
c (10 + (12 - 2)) / 12 = 8
C 10 + (12 - 2) = 8 
   
     00001110
    +10001110
    因为有符号位,我们计算的结果是错误的,所以我们希望转化为两个无符号的数字,通过上面的分析,我们希望转化为下面
     00001110
    -00001110
    此时去掉了符号位,如果直接相减,得到的结果0就是我们想要的结果,但是此时需要计算机实现符号位的自动处理,这在实现上会很复杂,但是通过上面的分析我们可以得到下面的式子
                          00001110
                         -00001110
    ----————————————————————————————
                            ⬇️
                      
                          00001110
    +         100000000 - 00001110
    ----————————————————————————————
                            ⬇️
                            
                          00001110  
    + (00000001+01111111)-10001110   
    ----————————————————————————————
                            ⬇️
                     
                          00001110
    + 00000001+(01111111-10001110)                 
    ----————————————————————————————
100000000-00001110 = (00000001+01111111)-10001110 = 00000001+(01111111-10001110) = 11110010
   00001110
  +11110010
  ----------
  100000000 
  
192-64
192+256-64
                            11000000
              +100000000 -  01000000  
     ------------------------------------------------------------------      
                         ⬇️
              
                            11000000
    + 00000001 + 01111111 - 01000000  
    ------------------------------------------------------------------ 
                         ⬇️
                         
                            11000000
    + 00000001 +(01111111 - 01000000) 
    ------------------------------------------------------------------ 
                         ⬇️ 
    
                            11000000
               + 00000001  +00111111
    ------------------------------------------------------------------ 
                         ⬇️ 
                            11000000
                           +01000000
    ------------------------------------------------------------------
                            10000000

10000000B=128,此时,时钟又回到了128点,我们的结果正确了

192+256-64 = 192+(256-64) =192+(1+255-64) = 192+(1+(255-64)),我们换成二进制的计其数的写法,应该是这样的

我们知道这两个式子的计算结果是相等的,于是就按照第二个式子进行做吧

其实我们完全可以忘掉上面的时钟,我们想象一下每天有256个小时,那么我们的钟表是这样的,我认为这样更好理解一些。接下来还是按照很笨的方法进行计算

这其中,我们经历了数字的拆分,运算的合并,就像小学时候的快速运算法(9+6+4=?,我们就会先运算6+4),至此我们明白了为什么负数的反码等于按位取反之后再加上1了。

于是我们把这一系列的过程得到的机器码叫做反码,并且知道了,反码的值等于按位取反之后,再加上数字1,这一列的操作可以用下面的这幅图来表示

  • 把一个负数(-a)等价换算为模-这个数字的绝对值,即 100000000-a

  • 把100000000 等价为00000001+01111111

  • 此时计算01111111-a,此时得到的结果是a的按位取反的值

  • 加上最前面的数字00000001,即再加上1

此时我们进行取模运算100000000/256=0,其实不进行取模运算的话,一个字节的长度只有8位,最高位的1已经被舍弃了,式子的结果还是等于0,于是我们实现了14+(-14)的机器运算的正确结果,此时回忆一下这个式子我们做了什么

如果我们先计算括号中的式子就会发现,得到的数字就是-14的按位取反,即每一个比特上面的数字全部取反,那么最后再加上最前面的1,我们可以得到如下的式子

因为100000000 = 00000001+01111111,所以我们把100000000 - 00001110 拆成了(00000001+01111111)-10001110,为什么要这样拆呢,是因为我们为了拆成最后的式子,即

其实,我们还可以有一个更好的理解,不去计算到底要走快多少时间,我们认为我们的智商很低,让钟表再走快12小时,那么就是10+12,也就是又多转了一圈,那么还是走到了10点,然后再倒退两小时,那么结果还是10+12-2,然后我们只要改变一下运算顺序就可以了,即10+(12-2),接下里的步骤就是对(12-2)这个式子进行拆拆补补。

接下来我们看看我们会得到怎么样的结论

另外一种笨的办法就是让他走快一些,快多少呢,我们需要拨快的时间是12-2=10小时

我们都知道生活中的时钟的例子,假如现在的时间是10点,并且假如我们的钟表快了2小时,那么我们最容易想到的办法就是往回倒走2小时,我们通常会想到的算式是:

那么此时的10011100B=?,计算结果是-28,这显然跟我们的预期不相符合。

我们知道14-14 = 14+(-14),计算一下得知

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

micro_cloud_fly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值