前导(如果你不了解原码除法,建议阅读,之后再看补码除法,更容易理解)
恢复余数法
补码的除法和无符号数除法的过程类似,但又有些许不同。
- 补码运算需要符号位和数值位一起参与运算。
- 中间余数是否够减除数,不看新中间余数(中间余数减除数的结果)的符号位,看的是新中间余数与原中间余数的符号位是否一致,一致表示够减,不一致表示不够减。
- 不像无符号数每次中间余数减除数。看的是被除数或中间余数与除数的符号,同号做减法,异号做加法
- 如果除数和被除数同号,商的符号应该是正;如果除数和被除数异号,商的符号应该是负。如果商的符号错了,则需要对商进行求补(各位取反,末尾加一)。
根据上面的话画一个表就是:
中间余数的符号 | 除数的符号 | 新中间余数的符号 | 是否够减 | 运算 |
---|---|---|---|---|
0 | 0 | 0 | 够 | 减 |
0 | 0 | 1 | 不够 | 减 |
0 | 1 | 0 | 够 | 加 |
0 | 1 | 1 | 不够 | 加 |
1 | 0 | 0 | 不够 | 加 |
1 | 0 | 1 | 够 | 加 |
1 | 1 | 0 | 不够 | 减 |
1 | 1 | 1 | 够 | 减 |
实现步骤:
- 除数装入除数寄存器Y,被除数经符号扩展后装入余数寄存器R和商寄存器Q
- R和Q同时左移一位
- 若R与Y同号,则R=R-Y。否则,R=R+Y。
- 若R=0或R操作前后符号未变,表示够减,上商为1。
- 若R操作前后符号变了,表示不够减,上商为0。恢复余数R值。
- 重复操作2,3直至取得n位商。
- 若商符号正确,则Q中的就是商。否则,对Q中的值求补才是正真的商。
- R中的就是余数。
举个例子:
-7/4=?
-7的补码是1001
4的补码是0100,4的变补码是1100
余数R | 商Q | 说明 |
---|---|---|
1111 | 1001 | 此值是被除数,作为中间余数的初始值 |
1111 | 0010 | 将上面的数左移(1次) |
0100 | 0000 | 此值是除数 |
0011 | 0010 | 由于上面两数异号,所以相加,得到的结果在左边 |
1100 | 0000 | 新中间余数(0011)和原中间余数(1111)的符号位不同,不够减,上商为0,然后加1100恢复余数 |
1111 | 0010 | 此值是恢复余数之后的值 |
1110 | 0100 | 将上面的数左移(2次) |
0100 | 0000 | 此值是除数 |
0010 | 0100 | 由于上面两数异号,所以相加,得到的结果在左边 |
1100 | 0000 | 新中间余数(0010)和原中间余数(1110)的符号位不同,不够减,上商为0,然后加1100恢复余数 |
1110 | 0100 | 此值是恢复余数之后的值 |
1100 | 1000 | 将上面的数左移(3次) |
0100 | 0000 | 此值是除数 |
0000 | 1000 | 由于上面两数异号,所以相加,得到的结果在左边 |
1100 | 0000 | 新中间余数(0000)和原中间余数(1100)的符号位不同,不够减,上商为0,然后加1100恢复余数 |
1100 | 1000 | 此值是恢复余数之后的值 |
1001 | 0000 | 将上面的数左移(4次) |
0100 | 0000 | 此值是除数 |
1101 | 0000 | 由于上面两数异号,所以相加,得到的结果在左边 |
1101 | 0001 | 新中间余数(1101)和原中间余数(1001)的符号相同,够减,上商为1,且不用恢复余数。循环了4次,求得商 |
由于除数和被除数的符号相异,所以商的符号应为负,但这里0001的符号是正,需要对0001求补,得到1111。
商1111对应的值是-1,余数1101对应的值是-3。
不恢复余数法
实现步骤:
- 除数装入除数寄存器Y,被除数经符号扩展后装入余数寄存器R和商寄存器Q
- 求第一位商,若R与Y同号,则R=R-Y。否则,R=R+Y。
- 若新的R与Y同号,则上商为1
- 若新的R与Y异号,则上商为0
- 第一位商用来判断是否溢出,不是正真的商。X与Y同号时上商为1或异号时上商为0都是溢出。
- 循环n次
- 若R与Y同号,则上商为1。
- 若R与Y异号,则上商为0。
- 将Q寄存器左移,此时最高位移出。
- 商的修正:被除数与除数同号,Q中就是正真的商。否则将Q的值加1才是正真的商
- 余数的修正:余数符号与被除数同号,R中就是正真的余数。否则:
- 被除数与除数符号相同,R的值加除数才是正真的余数。
- 被除数与除数符号不同,R的值减除数才是正真的余数。
注:每次上商都在左移之后(R乘2就是左移)
例如,求-5/2的值?
-5的补码是1011
2的补码是0010,2的变补码是1110。
余数R | 商Q | 说明 |
---|---|---|
1111 | 1011 | 此值是被除数,作为中间余数的初始值 |
0010 | 0000 | 上面的值与除数异号,所以加0010(+Y) |
0001 | 1011 | 此值是上面两值的和 |
0011 | 0111 | 因为R的符号(0001)与Y(0010)相同,所以左移时上商为1。(第一位商) |
1110 | 0000 | 上面的值与除数同号,所以加1110(-Y) |
0001 | 0111 | 此值是上面两值的和 |
0010 | 1111 | 因为R的符号(0001)与Y(0010)相同,所以左移时上商为1 |
1110 | 0000 | 上面的值与除数同号,所以加1110(-Y) |
0000 | 1111 | 此值是上面两值的和 |
0001 | 1111 | 因为R的符号(0000)与Y(0010)相同,所以左移时上商为1 |
1110 | 0000 | 上面的值与除数同号,所以加1110(-Y) |
1111 | 1111 | 此值是上面两值的和 |
1111 | 1110 | 因为R的符号(1111)与Y(0010)相异,所以左移时上商为0 |
0010 | 0000 | 上面的值与除数异号,所以加0010(+Y) |
0001 | 1110 | 此值是上面两值的和 |
0001 | 1101 | 因为R的符号(0000)与Y(0010)相同,只将Q寄存器左移,上商为1(将第一位商1移出) |
因为被除数与除数异号,所以Q的值加一1110才是正真的商,对应的十进制值是-2。
因为余数符号与被除数异号且被除数与除数符号不同,所以R的值0001加1110才是正真的余数,1111对应的十进制是-1。
判断是否同号与恢复余数法不同,不是新老余数之间,而是余数和除数之间