计组——关于二进制除法的一些思考

由于时间比较紧张,所以这次写的博客比较粗糙,望各位海涵,如果哪里写错了,您可以评论或者私聊指出我的错我,我一定马上改正。谢谢。

原码除法

恢复余数法

👉我们面临的问题

如何确定某个位置应该商几?

在这里插入图片描述

在这里插入图片描述

如果这个位置商1的话,则如下

在这里插入图片描述

好家伙,根本不够减,赶紧拿出橡皮擦擦掉刚刚的1,换成0,然后继续计算。

在这里插入图片描述

在这里插入图片描述

但是计算机还是比人笨的,我们人类能直接擦掉重新改,但是计算机可以吗?

如果您看过我之前的博文,或者了解计算机内部的乘法计算,就应该知道,计算机在计算乘除法的时候使用寄存器来存储中间结果,比如乘法的部分积,或者我们目前正在谈的除法中的余数,还是回到刚刚的问题

在这里插入图片描述

这个位置应该商什么?

计算机判断谁大谁小本身就是使用减法的结果来判断的(当然在计算机内部是使用的补码,这里我们仅仅用原码来展示一下原理),假设我们商1,那么就像这样:

在这里插入图片描述

最后两行很明显被减数小于减数,两者相减的结果无论正负最终都要存入余数的寄存器中,这时候我们检查寄存器里面的结果,发现,噢!原来商1后的余数为负数,不行,这个位置应该商0。

多么像你的人生,当你知道错了的时候,往往事情已经无法挽回了,寄存器里面已经存入一个负数了。

👉计算机是怎么做的

这时候我们要扭转自己作为一个正常人类在做除法时的观念。

在这里插入图片描述

作为计算机,你虽然笨,但你足够严谨,而且你在做除法的时候只需要关心商1还是0,所以你先进行验证然后再商。我们还是用这个老图。

在这里插入图片描述

面对这个问题,你到底商几?

如果我们默认商1(我只是说如果,我先不商,我先验证),0.0001010就需要减去0.0001101,先做减法,发现最终结果小于零(重申:计算机内部是使用的补码,这里我们仅仅用原码来展示一下原理),并且这个小于0的结果已经存入了余数寄存器中。

在这里插入图片描述

这时候你就要进行判断

  1. 余数寄存器中的值小于0,表示不能商1,需要商0
  2. 余数寄存器中的值大于0,表示能商1

好像我们完成了一个重大任务,我们把这个位置的正确商值求出来了!

在这里插入图片描述

Wait a minute,寄存器里面此时还存着一个负数呢!如果商0的话,寄存器里面的值不应该发生变化呀,怎么办?终于谈到了我们的正题——恢复余数。

这个时候我们则需要对余数寄存器再进行一步操作,它之前减去了一个除数,再给它加上一个除数,不就把它恢复了吗?

我们每轮上商之前需要进行的操作:

  1. 默认让余数减去除数
  2. 进行判断
    1. 余数寄存器中的值小于0,表示不能商1,需要商0,并且要对寄存器中的值进行恢复处理
    2. 余数寄存器中的值大于0,表示能商1

👉怎么做题?

关于移位:

首先,在计算的时候我们采用的是余数左移,形成对比记忆,乘法里面使用的都是右移,

关于左移,我用自己匮乏的语言能力没法说清楚,但是用一张图可以很好地理解,比如对于我们这道题来说,每次得到余数后,我们在下一位上商,假设我们上的商为1,比如你在小数点后第二位上商1,0.01×0.1101=0.001101,而此时上一轮得到的余数为0.01001,我们则需要在这个余数后面补零,这样才能和0.001101对齐,而在计算机中,这个过程其实是左移。

在这里插入图片描述

前期的准备工作:

原码除法和原码乘法一样,结果的符号提前进行判断,我们需要获得被除数和除数的绝对值原码,或者说补码,反正正数的补码和原码一致。设它们为 被 除 数 绝 被除数_{绝} 除 数 绝 除数_绝

每次上商1的时候,原来的余数需要减去 除 数 绝 除数_绝 ,那必然是不得行,计算机不会做减法,只会做加法,所以我们还需要获得 − 除 数 绝 -除数_{绝} 的补码即 [ − 除 数 绝 ] 补 [-除数_绝]_补 []

所以我们需要提前准备的是

被 除 数 绝 被除数_{绝} 除 数 绝 除数_绝 [ − 除 数 绝 ] 补 [-除数_绝]_补 []

借用实际例题

【计算机组成原理 第二版 唐朔飞 p259 例6.24】

已知x=-0.1011,y=-0.1101,求 [ x y ] 原 [\frac{x}{y}]_原 [yx]

按照我们之前总结的,提前准备好三个数

被 除 数 绝 被除数_{绝} = x ∗ x^* x=0.1011

除 数 绝 除数_绝 = y ∗ y^* y=0.1101

[ − 除 数 绝 ] 补 [-除数_绝]_补 []= [ − y ∗ ] 补 [-y*]_补 [y]=1.0011

在这里插入图片描述

计算出商为0.1101后,我们再根据原来的符号判断结果的正负

1 ⨁ 1 = 0 1\bigoplus 1 = 0 11=0

最终结果为0.1101

很重要的一个点

在这里插入图片描述

最后结果中的最高位置有判断溢出的功能,如果为1的话,则表示此除法溢出。

一图胜千言,其实光看看这个图就啥都理解了。

加减交替法

👉在恢复的过程中干了什么?

(在恢复余数算法中)当我们发现余数为负数的时候我们需要做什么?
在这里插入图片描述

标黄的部分可以表示为

( 余 数 + [ y ∗ ] 补 ) × 2 + [ − y ∗ ] 补 (余数+[y^*]_补)\times 2 + [-y^*]_补 (+[y])×2+[y]

其实我们完全可以把这个过程压缩,变成:

余 数 × 2 + [ y ∗ ] 补 + [ y ∗ ] 补 + [ − y ∗ ] 补 余数\times 2 + [y^*]_补 + [y^*]_补 + [-y^*]_补 ×2+[y]+[y]+[y]

$ [y^]_补 + [-y^]_补$其实相当于啥都没干,直接消除,变成

余 数 × 2 + [ y ∗ ] 补 余数\times 2 + [y^*]_补 ×2+[y]

也就是说如果余数为负数,我们只需要将余数乘以2(即左移一位)并且加上 [ y ∗ ] 补 [y^*]_补 [y]即可

👉做题

我们尝试能否把标黄的部分进行化简

在这里插入图片描述

这里我没有完全化简,你可以看到上面还有一处红字,我只是想要表达,加减法交替和恢复余数法本质上是等价的,加减法交替只是为恢复余数法做了个瘦身罢了。下面是完整的化简:

在这里插入图片描述

那么右边就是加减法交替的过程了,符号位还是老样子,提前计算好就行。

其前期准备是和恢复余数法一致的。

补码除法

够减?还是不够?

大家可以用平常的整数来增强理解。

当被除数和除数异号的时候,余数与除数异号,说明够减

在这里插入图片描述

当被除数和除数同号的时候,余数与除数同号,说明够减

在这里插入图片描述

确定商值

课本中指出,我们可以使用末位恒置1法

那么当 被 除 数 补 被除数_补 除 数 补 除数_补 同号的时候,商为正数补码,“够减”上商1,不够减上商0

那么当 被 除 数 补 被除数_补 除 数 补 除数_补 异号的时候,商为负数补码,“够减”上商0,不够减上商1

这里我需要解释一下异号的时候为什么会这样:

这与两个因素有关:①“末位恒置1法”②商的位数是固定的。

举个例子吧,比如一个二进制数-10010000,它的补码是?

我们知道,首位为1,标志着负数,后面为原来的数值部分取反加一,即 [ − 10010000 ] 补 [-10010000]_补 [10010000]=100000000 + (01101111 + 1) = 1 01110000

在后面的数值位中,哪些位置是仅仅被取反的?

1 01110000

到这一步你应该理解,低位的所有0,都是取反之后加一的过程中由于进位产生的。

所有可以这么说:补码中第从低位起,第一个不为0的位置以及该位置之前的高位,都仅仅是原码对应位的反码

那么如果我们使用了**“末位恒置1法”**,即我们将进位扼杀在了最低位置中,那么按照常理来说,异号的时候够减应该商1,但考虑到商又是负数,所以结果直接取反码就行了,因为我们计算过程中得到的所有位都在最低位之前。而由于“末位恒置1”法,这些位直接取反码即可。

在这里插入图片描述

利用统计学、概率论等等高端知识……哦,我考数二,没学概率论,打扰了,

利用我一个正常本科生的常识来看,总共是四种情况,而且不论 [ 被 除 数 ] 补 [被除数]_补 [] [ 除 数 ] 补 [除数]_补 []是同号还是异号,只要 [ 余 数 ] 补 [余数]_补 [] 除 数 ] 补 除数]_补 ]同号,商都是1,相反如果他俩异号,则商0。

那么我们的表格更新为:

在这里插入图片描述

计算过程

首先,补码计算过程的符号是自动生成的,你只管做,符号它会自动确定。

然后是一些表格,比起书上的那些表格,我觉得下面这个表格更重要:

在这里插入图片描述

[ 被 除 数 ] 补 [被除数]_补 [] [ 除 数 ] 补 [除数]_补 []异号时,是通过 [ 被 除 数 ] 补 + [ 除 数 ] 补 [被除数]_补 + [除数]_补 []+[]来获得余数的,所以对于异号来说,不够减的时候,余数左移之后应该是减去 [ 除 数 ] 补 [除数]_补 []即加上 [ − 除 数 ] 补 [-除数]_补 []

化简一下

在这里插入图片描述

【计算机组成原理 第二版 唐朔飞 p266 例6.27】

已知x=-0.1001,y=+0.1101,求 [ x y ] 补 [\frac{x}{y}]_补 [yx]

还是准备三样:

[ x ] 补 , [ y ] 补 , [ − y ] 补 [x]_补, [y]_补, [-y]_补 [x],[y],[y]

[ x ] 补 = 1.0111 [x]_补 = 1.0111 [x]=1.0111

[ y ] 补 = 0.1101 [y]_补 = 0.1101 [y]=0.1101

[ − y ] 补 = 1.0011 [-y]_补 = 1.0011 [y]=1.0011

在这里插入图片描述

记得最后一步左移后直接在最后一位补1即可

总结

无论原码除法还是补码除法,你判断他们结束的条件就是商形成了n+1位,即一个符号位和一个小数位。

最后DaoDao两句

之前写这个纯粹是由于气愤,自己学了多少次原码、补码的乘法除法,总是学了又忘,然后脑子一热,逼着自己写了两篇博客来加深印象,但是写博客以及作图的过程太累了/(ㄒoㄒ)/~~。

凡是不能杀死我的必会让我更强大,祝大家早日获得图灵奖。

复习去了。
在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值