mirror of
https://github.com/Didnelpsun/CS408.git
synced 2026-02-08 05:14:48 +08:00
更新
This commit is contained in:
@@ -163,44 +163,144 @@ $D.X_1=1$
|
||||
|
||||
**例题** 设机器字长为$n+1=5$位(含$1$位符号位),其中$x$的原码为$1.1101$,$y$的原码为$0.1011$,采用原码一位乘法求$x\cdot y$。
|
||||
|
||||
解:其中$x$就是$-0.1101$,而$y$就是$+0.1011$。先抛去符号位,就得到$01101$和$01011$两个数据。
|
||||
解:其中$x$就是$-0.1101$,而$y$就是$+0.1011$。先抛去符号位的正负全部为正,就得到$01101$和$01011$两个数据。
|
||||
|
||||
将$MQ$、$ACC$、$X$都初始化为五位存储单元。$X$放入被乘数$01101$,$MQ$放入乘数$01011$,$ACC$为$00000$。
|
||||
|
||||
```txt
|
||||
ACC MQ 丢失位
|
||||
0 0 0 0 0 <--> ^ 0 1 0 1 1 |
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
运算器结构:$ACC$与$MQ$相连,数据流是双向的,$ACC$与$ALU$相连,数据流是双向的,$X$的数据流向$ALU$。
|
||||
|
||||
此时$MQ=01011$,作为乘法单位的最后位为$1$,所以$ACC+=X$,从而$ACC=00000+01101=01101$,这就是第一个的位积。
|
||||
此时$MQ=01011$,作为乘法单位的最后位为$1$,所以$ACC+=X$,从而$ACC=00000+01101=01101$,这就是第一个的位积。(其中^左边的即计算的结果,即部分积)
|
||||
|
||||
```txt
|
||||
ACC MQ 丢失位
|
||||
0 1 1 0 1 <--> ^ 0 1 0 1 1 |
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
由于按照乘法规则,第二个位积计算时需要错位相加,计算机的处理方式是$ACC$和$MQ$的数据连在一起,全部逻辑右移一位(左边补$0$)。
|
||||
|
||||
```txt
|
||||
ACC MQ 丢失位
|
||||
0 0 1 1 0 <--> 1 ^ 0 1 0 1 | 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
所以$ACC$的数据由$01101$变为$00110$,最后的$1$移到$MQ$最高位,$MQ$由$01011$变为$10101$,最后的一位$1$溢出被抛弃,代表这一位的位积已经计算并相加完成,所以不用管了。此时结果的高位还在$ACC$中,而结果的低位从$ACC$移到了$MQ$中,在$MQ$的低位也不参与后面的运算,所以也不用管了。
|
||||
|
||||
然后计算下一个最低位的位积,此时$MQ$的最低位还是$1$,所以$ACC+=X=00110+01101=10011$。
|
||||
|
||||
```txt
|
||||
ACC MQ 丢失位
|
||||
1 0 0 1 1 <--> 1 ^ 0 1 0 1 | 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
同样计算完后再错位,进行逻辑右移,$ACC$由$10011$变成了$01001$,$MQ$由$10101$变成了$11010$,最低位的$1$被抛弃,此时$MQ$中已经有两个结果最低位。
|
||||
|
||||
```txt
|
||||
ACC MQ 丢失位
|
||||
0 1 0 0 1 <--> 1 1 ^ 0 1 0 | 1 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
此时$MQ$最低位为$0$,所以$ACC$保持不变,再逻辑右移一位,$ACC$由$01001$变为$00100$,$MQ$由$11010$变为$11101$,抛弃一位$0$,$MQ$有三个结果最低位。
|
||||
|
||||
```txt
|
||||
ACC MQ 丢失位
|
||||
0 0 1 0 0 <--> 1 1 1 ^ 0 1 | 0 1 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
此时$MQ$最低位为$1$,则$ACC+=X=00100+01101=10001$。
|
||||
|
||||
```txt
|
||||
ACC MQ 丢失位
|
||||
1 0 0 0 1 <--> 1 1 1 ^ 0 1 | 0 1 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
同样计算完后再错位,进行逻辑右移,$ACC$由$10001$变成了$01000$,$MQ$由$11101$变成了$11110$,最低位的$1$被抛弃,此时$MQ$中已经有四个结果最低位,此时$MQ$最低位是代表符号的$0$不参与运算。此时计算已经结束。
|
||||
|
||||
小数的小数点隐藏在第一位的后面,所以此时结果在$ACC$和$MQ$的前四位中,即$0.10001111$。最后加上符号异或结果,得到$1.10001111$。
|
||||
```txt
|
||||
ACC MQ 丢失位
|
||||
0 1 0 0 0 <--> 1 1 1 1 ^ 0 | 1 0 1 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
小数的小数点隐藏在第一位的后面,所以此时结果在$ACC$和$MQ$的前四位中,即$0.10001111$。最后加上符号异或结果$x\oplus y=0\oplus1=1$,得到$1.10001111$。
|
||||
|
||||
上面是计算具体的物理逻辑过程,逻辑的求解过程如下:
|
||||
|
||||
被乘数在$X$中,其结果在每次的第三行,左边的第一行为$ACC$没有右移的结果,第二行为右移的结果,右边的为$MQ$的内容。
|
||||
被乘数在$X$中,其结果在每次的第三行,左边的第一行为$ACC$没有右移的结果,第二行为右移的结果,右边的为$MQ$的内容。原码一位乘法可以使用单符号位也可以使用双符号位。
|
||||
|
||||
![原码一位乘法][yuanmayiwei]
|
||||
|
||||
补码一位乘法
|
||||
|
||||
**例题** 设机器字长为$n+1=5$位(含$1$位符号位),其中$x$的原码为$-0.1101$,$y$的原码为$0.1011$,采用原码一位乘法求$x\cdot y$。
|
||||
**例题** 设机器字长为$n+1=5$位(含$1$位符号位),其中$x$的原码为$-0.1101$,$y$的原码为$+0.1011$,采用补码一位乘法求$x\cdot y$。
|
||||
|
||||
其中下划线的左边一个为$MQ$最低位,右边一个为辅助位。
|
||||
解:
|
||||
|
||||
由于需要使用补码,且需要$-x$的补码,所以$[x]_{\text{补}}=1.0011$,$[-x]_{\text{补}}=0.1101$,$[y]_{\text{补}}=0.1011$。
|
||||
|
||||
将$MQ$、$ACC$、$X$都初始化为六位存储单元。$ACC$和$X$都使用双符号位补码,$MQ$使用单符号位补码,$X$放入被乘数补码$11.0011$,$MQ$放入乘数补码$00.1011$,$ACC$为$000000$。辅助位初始化为$0$。
|
||||
|
||||
```txt
|
||||
ACC MQ 辅助位 丢失位
|
||||
0 0 0 0 0 0 <--> 0 1 0 1 1 | 0 |
|
||||
|
|
||||
ALU
|
||||
|
|
||||
1 1 0 0 1 1
|
||||
X
|
||||
```
|
||||
|
||||
其中下划线的左边一个为$MQ$最低位,右边一个为辅助位,根据辅助位-$MQ$最低位判断加的是$x$补码的哪个值。
|
||||
|
||||
是双符号位,但是右移时将两个符号位视为一个一起移动。
|
||||
|
||||
![补码一位乘法][bumayiwei]
|
||||
|
||||
最后一次再根据条件判断加什么,加后不需要右移即是结果(这里让符号位参与运算)。当被乘数全部移出部分积计算结束。($n$轮,$n$为数值位)
|
||||
|
||||
所以$x\cdot y=-0.10001111$。
|
||||
|
||||
**例题** 有实现$x\times y$的两个$C$语言函数如下:
|
||||
@@ -242,46 +342,216 @@ int imul(int x, int y){
|
||||
|
||||
**例题** 设机器字长为$5$位(含一位符号位),$x=0.1011$,$y=0.1101$,采用原码恢复余数法求$x\div y$。
|
||||
|
||||
其中$x$就是$+0.1011$,而$y$就是$+0.1101$。先抛去符号位,就得到$01011$和$01101$两个数据。然后求出$y$绝对值的补码:$01101$和$-y$绝对值的补码:$10011$。
|
||||
其中$x$就是$+0.1011$,而$y$就是$+0.1101$。先抛去符号位,就得到$01011$和$01101$两个数据。然后求出$\vert y\vert$的补码:$01101$和$-\vert y\vert$的补码:$10011$。
|
||||
|
||||
将$MQ$、$ACC$、$X$都初始化为五位存储单元。将被除数$01011$放入$ACC$中,将除数$01101$放入$X$中,商初始化为$00000$。
|
||||
为什么是原码却要求补码?因为在除法中,每一步都要将当前部分被除数$x_i$与这个位的部分商$q_i=[0|1]$与除数$y$相乘得到的乘积$p=q_i\times y$相减得到余数即下一个被除数$x_{i+1}$。
|
||||
|
||||
手算时每位商取$0/1$是通过判断当前余数和除数的大小确定的。而机器实现时就要通过$ALU$判断是$ACC$中的数更大还是$X$中的数更大,如果$ACC$的更大就商$1$,若$X$的更大就商$0$。
|
||||
所以需要用到原码的减操作,但是原码不好进行减操作运算,补码更容易进行减操作运算。
|
||||
|
||||
第一位默认商$1$,$ACC-=X$,$ACC$的$01011$和$X$的$10011$($X$实际值的负值的补码)输入$ALU$进行加操作$01011+10011=11110$,返回给$ACC$,此时发现代表符号的最高位为$1$,代表出现了负数,就表明之前的商出错了,所以重新确定商为$0$,$ACC$要恢复余数,从而再加上$y$的补码:$11110+01101=01011$。
|
||||
而对于补码的减操作$[x_i-p]_{\text{补}}=[x_i+(-p)]_{\text{补}}=[x_i]_{\text{补}}+[-p]_{\text{补}}$,又在除法中是要找让与除数的乘积最大且不超过被除数的余数,所以$x_i>p$必然成立,所以$x_i-p>0$必然成立,而正数的补码和原码相等,所以$[x_i-p]_{\text{原}}=[x_i-p]_{\text{补}}=[x_i]_{\text{补}}+[-p]_{\text{补}}$。
|
||||
|
||||
第一位的商计算完后需要进行计算,错位相除,所以同乘法一样,$ACC$和$MQ$的值都要逻辑左移一位,低位补$0$,所以$MQ$由$00000$还是变为$00000$,$MQ$的最高位的$0$移到$ACC$最低为,$ACC$最高位丢弃,由$01011$变成$10110$。
|
||||
将$MQ$、$ACC$、$X$都初始化为五位存储单元。将被除数$01011$放入$ACC$中,将除数$01101$放入$X$中,商在$MQ$初始化为$00000$。当前要确定的商的位数是$MQ$中最低一位。
|
||||
|
||||
然后第二位默认商$1$,同样$ACC-=X$,$10110+10011=01001$,将这个值赋给$ACC$,发现符号位为$0$,代表正,商就没有问题,$MQ$为$00001$。
|
||||
```txt
|
||||
ACC MQ
|
||||
0 1 0 1 1 <--> 0 0 0 0 0 ^
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
手算时每位商取$0/1$是通过心算判断当前余数和除数的大小确定的。而机器实现时就要通过$ALU$判断是$ACC$中的数更大还是$X$中的数更大,如果$ACC$的更大就商$1$,若$X$的更大就商$0$。(商应该让乘积小于当前$ACC$中的被除数$x_i$)
|
||||
|
||||
但是实际上恢复余数法中计算机每次会默认商$1$,如果错误($ACC$得到的结果为负数)再修改为商$0$,并且恢复余数。
|
||||
|
||||
第一位默认商$1$,$ACC-=X$,$ACC$的$01011$和$X$的$10011$($x$实际值的负值的补码)输入$ALU$进行加操作$01011+10011=11110$,返回给$ACC$,此时发现代表符号的最高位为$1$,代表出现了负数,就表明之前的商出错了(因为我们去掉了符号,所以除数与被除数都是正数不可能是负数)。
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
1 1 1 1 0 <--> 0 0 0 0 ^ 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
所以重新确定商为$0$,$ACC$要恢复余数,从而再加上$y$的补码:$11110+01101=01011$。(因为原来加上了$-y$的补码,相当于减去了$y$,此时加上$y$结果重新变成了正数,正数的补码等于正数的原码)
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
0 1 0 1 1 <--> 0 0 0 0 ^ 0
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
第一位的商计算完后需要进行计算,错位相除,所以同乘法一样,$ACC$和$MQ$的值都要逻辑左移一位,低位补$0$,所以$MQ$由$00000$还是变为$00000$,$MQ$的最高位的$0$移到$ACC$最低位,$ACC$最高位丢弃,由$01011$变成$10110$。
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
1 0 1 1 0 <--> 0 0 0 ^ 0 0
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
然后第二位默认商$1$,同样$ACC-=X$,$10110+10011=01001$(高位溢出直接丢弃),将这个值赋给$ACC$,发现符号位为$0$,代表正,商就没有问题,$MQ$为$00001$。
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
0 1 0 0 1 <--> 0 0 0 ^ 0 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
再次逻辑左移一位,$MQ$由$00001$变为$00010$,$ACC$由$01001$变为$10010$。
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
1 0 0 1 0 <--> 0 0 ^ 0 1 0
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
第三位默认商$1$,同样$ACC-=X$,$10010+10011=00101$,商没有问题,$MQ$为$00011$。
|
||||
|
||||
再次逻辑左移一位,$MQ$由$0$0011$$变为$$0011$0$,$ACC$由$00101$变为$01010$。
|
||||
```txt
|
||||
ACC MQ
|
||||
0 0 1 0 1 <--> 0 0 ^ 0 1 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
第四位默认商$1$,同样$ACC-=X$,$01010+10011=11101$,高位为$1$,商应该为$0$,$MQ$变为$00110$,$ACC$恢复余数:$11101+01101=01010$。
|
||||
再次逻辑左移一位,$MQ$由$00011$$变为$00110$,$ACC$由$00101$变为$01010$。
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
0 1 0 1 0 <--> 0 ^ 0 1 1 0
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
第四位默认商$1$,同样$ACC-=X$,$01010+10011=11101$,高位为$1$。
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
1 1 1 0 1 <--> 0 ^ 0 1 1 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
商应该为$0$,$MQ$变为$00110$,$ACC$恢复余数:$11101+01101=01010$。
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
0 1 0 1 0 <--> 0 ^ 0 1 1 0
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
再次逻辑左移一位,$MQ$由$00110$变为$01100$,$ACC$由$01010$变为$10100$。
|
||||
|
||||
```txt
|
||||
ACC MQ
|
||||
1 0 1 0 0 <--> ^ 0 1 1 0 0
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
第五位默认商$1$,同样$ACC-=X$,$10100+10011=00111$,高位为$0$,商没有问题,$MQ$为$01101$。
|
||||
|
||||
此时计算结束,商为$01101$,余数为$00111$。余数还要乘上$2^{-n}=2^{-4}$。
|
||||
```txt
|
||||
ACC MQ
|
||||
0 0 1 1 1 <--> ^ 0 1 1 0 1
|
||||
|
|
||||
ALU
|
||||
|
|
||||
0 1 1 0 1
|
||||
X
|
||||
```
|
||||
|
||||
此时计算结束,商为$01101$,并乘上$x\oplus y=0\oplus0=0$为正数,所以商还是$01101$。余数为$00111$,余数还要乘上$2^{-n}=2^{-4}$才为真值($n$为除法步骤轮次或数值位)。
|
||||
|
||||
![huifuyushu]
|
||||
|
||||
源码的加减交替法:
|
||||
原码的加减交替法:
|
||||
|
||||
余数为负,则商$0$,左移,加上除数绝对值。
|
||||
不恢复余数法本质只是将恢复余数法的流程进行压缩整合,原理是一样的,因为减去加上同一个值很浪费时间所以对其进行优化。如上面的计算例子,定义$+[-\vert y\vert]_{\text{补}}=-$,$+[\vert y\vert]_{\text{补}}=+$,左移为$<$,设$y$绝对值补码为$b$:
|
||||
|
||||
余数为正,则商$1$,左移,减去除数绝对值。
|
||||
序号|操作|被除数/余数|商|说明
|
||||
:--:|:--:|:---------:|:-:|:-:
|
||||
1||0.1011||
|
||||
2|-|1.1110|0|结果为负,设余数为a,商0
|
||||
3|+|0.1011|0|a+b,恢复余数
|
||||
4|\<|1.0110|0|(a+b)×2=2a+2b
|
||||
5|-|0.1001|0|2a+2b-b=2a+b
|
||||
|
||||
补码除法(不恢复余数法/加减交替法),异号相除是看够不够减,然后上商$1$,够减商$0$,不够减商1。
|
||||
从第二步减去除数绝对值$b$后就能根据结果判断当前位商$0$,然后$3$步加上绝对值恢复余数,一加一减浪费时间,可以直接从第二步跳到第五步。即如果出现负数余数不用恢复余数,将余数$a$左移一位加上$y$绝对值补码(原码)为$b$就得到下一轮的结果,然后直接对结果判断商。
|
||||
|
||||
余数为负,则商$0$,左移,加上除数绝对值;余数为正,则商$1$,左移,减去除数绝对值。
|
||||
|
||||
如上个例题使用原码加减交替法:
|
||||
|
||||
![buhuifuyushu]
|
||||
|
||||
如果最后一步余数位负,则需要商$0$,并加上$y$绝对值进行恢复余数。
|
||||
|
||||
补码除法(不恢复余数法/加减交替法),异号相除是看够不够减,然后上商$1$,够减商$0$,不够减商1。
|
||||
|
||||
补码的加减交替法:
|
||||
|
||||
与原码加减交替法类似,被除数、除数、余数要使用双符号位,符号位也参与运算。
|
||||
|
||||
**例题** 设机器字长为$5$位(含一位符号位),$x=+0.1000$,$y=-0.1011$,采用补码加减交替法求$x\div y$。
|
||||
|
||||
解:首先计算对应的补码,$[x]_{\text{补}}=00.1000$,$[y]_{\text{补}}=11.0101$,$[-y]_{\text{补}}=00.1011$。
|
||||
|
||||
原码的加减交替法第一步就是减去$y$绝对值的补码然后根据商进行判断,而补码的加减交替法首先就要判断,如果被除数除数同号,则被除数减去除数;异号则被除数加上除数。
|
||||
|
||||
得到余数后与除数符号进行判断,余数和除数同号,则商$1$,余数左移一位减去除数,余数和除数异号,商$0$,余数左移一位加上除数。重复$n$次。
|
||||
|
||||
除了第一步原码加减交替法是固定减法,其他的基本上两个方法是一样的。
|
||||
|
||||
所以第一步,由于$xy$是异号的,所以第一步是$x+y=00.1000+11.0101=11.1101$。由于除数符号也是$11$,所以同号商$1$,左移并减去除数,$11.1010+00.1011=00.0101$。
|
||||
|
||||
第二步,由于余数符号为$00$,而除数符号为$11$,所以异号,从而商$0$,左移并加上除数,$00.1010+11.0101=11.1111$。
|
||||
|
||||
第三步,由于余数符号为$11$,而除数符号为$11$,所以同号,从而商$1$,左移并减去除数,$11.1110+00.1011=00.1001$。
|
||||
|
||||
第四步,由于余数符号为$00$,而除数符号为$11$,所以异号,从而商$0$,左移并加上除数(注意这里双符号位就发生了异号,但是不影响),$01.0010+11.0101=00.0111$。
|
||||
|
||||
第五步,由于余数符号为$00$,而除数符号为$11$,所以异号,从而商$0$,但是这是最后这一位默认商$1$,所以不商$0$而是$1$。
|
||||
|
||||
所以商为$1.0101$,余数为$0.0111\times2^{-4}$(注意这里还是要乘一个$2^{-n}$)。
|
||||
|
||||
![jiajianjiaoti]
|
||||
|
||||
#### 定点数强制类型转换
|
||||
|
||||
@@ -380,7 +380,7 @@ k|2|3|4|5|6|7
|
||||
|
||||
#### 定点数乘法运算
|
||||
|
||||
对于原码的乘数运算可以参考十进制的乘数运算,将乘数一位一位的乘被乘数然后再全部错位相加得到的就是答案。
|
||||
二进制乘法运算可以参考十进制的乘法运算,将乘数一位一位的乘被乘数然后再全部错位相加得到的就是答案。
|
||||
|
||||
```txt
|
||||
318
|
||||
@@ -420,7 +420,9 @@ k|2|3|4|5|6|7
|
||||
10001111
|
||||
```
|
||||
|
||||
所以此时分析笔算二进制乘法就被拆解出了二进制乘法流程:将乘法变为加法和移位运算,将乘数一位位的向前移动并与被乘数相乘,由于是二进制所以只有$0$和$1$,遇到乘数当前位值为$1$就在原来的和上加上被乘数,并向前移动一位,如果是$0$就加上$0$继续移动一位,当乘数位数访问完成则乘法完成,所有的和相加称为最后的积。
|
||||
所以此时分析笔算二进制乘法就被拆解出了二进制乘法流程:将乘法变为加法和移位运算,将乘数一位位的向前移动并与被乘数相乘,由于是二进制所以只有$0$和$1$,遇到乘数当前位值为$1$就在原来的和上加上被乘数,并向前移动一位,如果是$0$就加上$0$继续移动一位,当乘数位数访问完成则乘法完成,所有的和相加成为最后的积。
|
||||
|
||||
这就是原码乘法的原理,可以考虑用机器实现,但是还是要考虑以下问题:如何处理符号?乘积位数扩大一倍是否可能超过机器字长?各个位积如何相加变成最后的乘积?
|
||||
|
||||
原码一位乘法:
|
||||
|
||||
@@ -450,13 +452,13 @@ k|2|3|4|5|6|7
|
||||
+ 为了加快运算会有辅助电路实现$(-x)$的补码的运算。
|
||||
+ 最后一次不需要移位直接根据辅助位和$MQ$最后一位判断进行相加。从而让乘数的符号位也参数运算中来确定最后结果的符号。
|
||||
+ 补码一位乘法逻辑运算:
|
||||
1. 初始化,左边为部分积,即计算的部分结果,最开始为全$0$,右边为乘数的绝对值,最后边全部为丢失位,丢失位第一个就是辅助位。
|
||||
2. 根据辅助位和$MQ$最低位的差的值来判断加上什么,若是$1$则加上被乘数的补码,若是$0$则加与被乘数等长的全$0$,若是$-1$则加上被乘数的负数的补码。
|
||||
1. 初始化,左边为部分积,即计算的部分结果,最开始为全$0$,右边为乘数,然后是一个辅助位,最后边全部为丢失位。
|
||||
2. 根据辅助位$-MQ$最低位的差值来判断加上什么,若是$1$则加上被乘数的补码,若是$0$则加与被乘数等长的全$0$,若是$-1$则加上被乘数的负数的补码。
|
||||
3. 算术右移部分积一位,正数高位补$0$,负数高位补$1$,丢失位多一位。
|
||||
4. 继续计算,直到乘数全部被移出。字长为$n+1$位则需要移位计算$n$次。丢失位前的就是全部部分积。
|
||||
5. 最后一次不需要移位,再加一次。
|
||||
|
||||
$Booth$算法的移位法则:
|
||||
$Booth$算法的移位法则,其中$y_n$为$MQ$最低位,$y_{n+1}$为辅助位:
|
||||
|
||||
$y_n$(高位)|$y_{n+1}$(低位)|操作
|
||||
:-----------:|:---------------:|:--:
|
||||
@@ -473,17 +475,68 @@ $y_n$(高位)|$y_{n+1}$(低位)|操作
|
||||
:----:|:--:|:--:
|
||||
计算流程|n轮加法、移位|n轮加法、移位,最后进行一次加法
|
||||
加法的值|+0、+x的原码|+0、+x的补码、+(-x)的补码
|
||||
判断加值的根据|MQ的最低位|MQ的最低位、辅助位
|
||||
判断加值的根据|MQ的最低位|辅助位-MQ的最低位
|
||||
判断关系|MQ的最低位=1时,ACC+x的原码;MQ的最低位=0时,ACC不变|辅助位-MQ中最低位=1时,(ACC)+x的补码;辅助位-MQ中最低位=0时,ACC不变;辅助位-MQ中最低位=-1时,ACC+(-x)的补码
|
||||
移位类型|逻辑右移|算术右移
|
||||
符号位|不参与运算|参与运算
|
||||
|
||||
#### 定点数除法运算
|
||||
|
||||
二进制除法运算可以参考十进制的除法运算,将除数乘上一位数,使得乘积最大且不超过被除数,然后将被除数减去这个乘积并左移就得到下一轮运算的被除数。
|
||||
|
||||
```txt
|
||||
1.507
|
||||
--------
|
||||
211 | 318
|
||||
211
|
||||
--------
|
||||
1070
|
||||
1055
|
||||
--------
|
||||
150
|
||||
000
|
||||
--------
|
||||
1500
|
||||
1477
|
||||
--------
|
||||
23
|
||||
...
|
||||
```
|
||||
|
||||
所以除法就是为了凑和被除数相近的商。
|
||||
|
||||
而使用二进制的一位位除法同理:
|
||||
|
||||
```txt
|
||||
0.1101
|
||||
------------
|
||||
01101 | 01011
|
||||
00000
|
||||
------------
|
||||
10110
|
||||
01101
|
||||
------------
|
||||
10010
|
||||
01101
|
||||
------------
|
||||
01010
|
||||
01101
|
||||
------------
|
||||
01010
|
||||
00000
|
||||
------------
|
||||
10100
|
||||
01101
|
||||
------------
|
||||
0111
|
||||
```
|
||||
|
||||
+ 进行除法操作时,都是为了找到一位能让商乘除数能最大即余数最小但大于$0$的值。若除数被除数都是小数,可以同时乘一个数变成整数再运算。
|
||||
+ 所以可以忽略小数点,每确定一位商进行一次减法,若机器字长为$n$位,则得到$n-1$位余数,在余数末尾补$0$,再确定下一位商$0$或$1$,直到确定$n$位商即可停止。
|
||||
+ 在运算器的组成时出现一个表格,说明在进行除运算时,$ACC$保存被除数和余数,$MQ$保存商,$X$保存除数。
|
||||
|
||||
所以同理可以推出恢复余数法,与源码一位法类似,都是计算绝对值最后判断符号。余数加$0$扩大余数就相当于左移一位。
|
||||
|
||||
原码恢复余数法:
|
||||
|
||||
物理上:
|
||||
@@ -544,6 +597,8 @@ $y_n$(高位)|$y_{n+1}$(低位)|操作
|
||||
原码加减交替法|否|N+1或N+2|左|N|余数的正负|若最终余数为负,需恢复余数
|
||||
补码加减交替法|是|N+1|左|N|余数和除数是否同号|商末位恒置1
|
||||
|
||||
其实本质上原码和补码的上商和加减原则是一样的,只是因为除数被去掉符号为正值,所以余数是负就异号,是正就同号。
|
||||
|
||||
#### 定点数强制类型转换
|
||||
|
||||
+ 无符号数与有符号数:不改变数据内容,只改变解释方式。
|
||||
@@ -562,7 +617,7 @@ $y_n$(高位)|$y_{n+1}$(低位)|操作
|
||||
+ 大端模式:将$MSB$存到最低地址,$LSB$存在最高地址。便于人类阅读。
|
||||
+ 小端模式:将$MSB$存到最高地址,$LSB$存在最低地址。便于机器读取。
|
||||
+ 边界对齐:
|
||||
+ 现代计算机通常是按字节编址即每个字节对应一个地址通常。也支持按字、按半字、按字节寻址。
|
||||
+ 现代计算机通常是按字节编址即每个字节对应一个地址。也支持按字、按半字、按字节寻址。
|
||||
+ 假设存储字长为$32$位,则$1$个字=$32bit$,半字$=16bit$。每次访存只能读/写$1$个字。
|
||||
+ 字地址转换为字节地址,只用逻辑左移两位就可以了,即乘以$4$,因为字长为$32$,而字节长$8$。
|
||||
+ 使用边界对齐方式会让每个数据都能一次性读完而不用跨行读取,多余的空间用$0$填充。
|
||||
|
||||
Reference in New Issue
Block a user