【学习计算机组成原理】原码除运算

现实生活中的除法

在这里插入图片描述
为了便于描述,我们这样做
在这里插入图片描述
步骤:

  1. 被除数减除数,被除数大,上商为1,被除数小,上商为0。
  2. 每次得到的差为中间余数,将除数右移后与中间余数比较,中间余数大,上商为1,中间余数小,上商为0。
  3. 循环步骤2,直到求得商的位数足够。

预处理

  1. 被除数为0,除数不为0,商为0。
  2. 定点整数,被除数小于除数,商为0。
  3. 定点整数,被除数不为0,除数为0,发生异常。
  4. 浮点数,被除数不为0,除数为0,产生无穷(inf/-inf)。
  5. 浮点数,被除数和除数都为0,产生非数(NaN)。

只有除数和被除数都不为0,商也不为0时,才进一步除法运算

无符号数的除法

模拟手工

如果两个n位数相除,需要将被除数扩展为2n位:

  1. 正整数:在被除数前加n个0
  2. 纯小数:在被除数后加n个0

根据现实中的除法,得出在机器中运算的关键步骤:

  1. 余数减除数得一个新余数
  2. 新余数大于0(表明够减),商左移上1。
  3. 新余数小于0(不够减),商左移上0,并恢复余数。
  4. 除数右移

流程图如下:

Created with Raphaël 2.2.0 开始 中间余数减除数 结果>=0? 商左移并上商为1 除数右移 循环够n+1次? 结束 商左移并上商为0,恢复余数 yes no yes no

比如:求7除2的值?
7的原码是0111,扩展之后是0000 0111。
2的原码是0010 0000,变补码是1110 0000。

除数 中间余数(默认为被除数) 中间余数减除数
0000 0010 0000 0000 0111 0000 0111+1110 0000=1110 0111<0
0000 0001 0000 0000 0111(恢复余数) 0000 0111+1111 0000=1111 0111<0
0000 0000 1000 0000 0111(恢复余数) 0000 0111+1111 1000=1111 1111<0
0000 0000 0100 0000 0111(恢复余数) 0000 0111+1111 1100=0000 0011>0
0001 0000 0010 0000 0011 0000 0011+1111 1110=0000 0001>0
0011 0000 0001 0000 0001 结束

结果是0011,表示商是2,中间余数是0000 0001,表示余数是1。
4位数,所以是5步
一开始的上商值是0,移了5次之后,在商中消失了,这个数其实是用来判断是否溢出的,如果是1,则代表溢出,即商无法用4位数表示。

优化

恢复余数法

如果被除数和除数都是n位,那么商一定不溢出,即n位一定可以表示两n位数的商。

商一开始的有四个没用的0,中间余数的前4位都是没用的0(在被除数是n位的前题下),因此可以合并商和中间余数,用8位就可表示4位中间余数和4位商。
如果除数不移动,那么除数的后4位也多余,所以想一个办法代替除数右移,就可以用4位表示除数。
这个办法就是中间余数左移(与除数右移效果一样),所以中间余数一开始应该放在右4位才可以左移。

所以最终确定,4位中间余数与4位商合并,前4位最终表示余数,后四位最终表示商,用4位表示除数。

除数(4位) 中间余数与商的合并位(4+4) 高4位减除数(4位)
0010 0000 0111 0000+1110=1110<0
(此步应省)
0010 0000 1110(恢复+左移) 0000+1110=1110<0
0010 0001 1100(恢复+左移) 0001+1110=1111<0
0010 0011 1000(恢复+左移) 0011+1110=0001>0
0010 0011 0001(左移) 0011+1110=0001>0
(此处0001即为余数)
0010 0010 0011(左移) 余数右移1位

因为合并位左移了5次,中间余数会多移一次,所以需要将0010右移一次,得到0001才是正确的余数。
由于除数和被除数都是n位,合并位的高n位一开始全为0,所以高n位减除数一定小于0,所以无需第一步判断差的结果,直接左移合并位并上商为0即可。

不恢复余数法(加减交替法)

上面的是恢复余数之后才左移,当然也可以不恢复余数。
我们看上面的第一步恢复余数

除数(4位) 中间余数与商的合并位(4+4) 高4位减除数(4位)
0010 0000 0111 0000+1110=1110<0
0010 0000 1110(恢复+左移) 0000+1110=1110<0

第一次中间余数减除数之后,中间余数变为1110,之后,1110+0010恢复成0000,然后左移,最低位补0(因为1110<0)。
我们也可以这样,第一次中间余数减除数之后,中间余数变为1110,之后,1110 0111左移,最低位补0,变为1100 1110,然后1100+0010就是下次高4位加除数的结果1110。

除数(4位) 中间余数与商的合并位(4+4) 高4位加/减除数(4位)
0010 0000 0111 0000+1110=1110<0
0010 1100 1110(左移) 1100+0010=1110<0

这里高4位是加还是减,取决于合并位的高4位,高4位大于等于0,做减法。高四位小于0,做加法。
最后一次若上商为0,需纠正余数,将余数加除数才是真正的余数。

比如5/3,5的二进制是0101,3的二进制是0011,3的变补是1101。

除数(4位) 中间余数与商的合并位(4+4) 高4位加/减除数(4位)
0011 0000 0101 0000+1101=1101<0(减法)
0011 1010 1010(上0) 1010+0011=1101<0(加法)
0011 1011 0100(上0) 1011+0011=1110<0(加法)
0011 1100 1000(上0) 1100+0011=1111<0(加法)
0011 1111 0000(上0) 1111+0011=0010>0(加法)
0011 0100 0001(上1) 纠正余数

0100+1101=0001,所以1是余数,0001是商。

原码除法

  • 符号位和数值位分开处理
  • 商和余数的值按无符号数值算
  • 商的符号,被除数与除数同号为正,异号为负
  • 余数的符号同被除数符号

猜你喜欢

转载自blog.csdn.net/weixin_44611096/article/details/105662179