5 整数运算

图片来源:南京大学软件学院COA课程PPT

©author:zzb

5 整数运算

image-20211218090925893

image-20211218090935971

image-20210928164942515

异或门是不能多个一起输入的,只能两两。a⊕b = (¬a ∧ b) ∨ (a ∧¬b),由此推断,非门的门延迟也为1ty

而与和或则可以多个一起输入,因为如或门,只要有一个1 ,那么结果就是1,与门,只要有一个0,那么结果都是0

串行进位加法器

image-20210928165948285

image-20210928170122630

之所以s=x⊕y⊕c,把x和y先做异或,是为了节省时间,因为c需要由前面的数据得到,如上,Cn的延迟是2n ty,因此可以提前把xn⊕yn计算好,等Cn-1计算好后再和Cn-1异或,因此Sn的延迟为2(n-1)+3=2n+1

但第一和第二位除外,它们的延迟都是6,因为得到C1为2,而此时X2和Y3还没有异或就绪,所以仍然是S2的延迟仍是6。C2的延迟是4>3,因此X3和Y3已经异或完成,在等C2

所有的Ai和Bi是同时输入的,等到Ci-1到来时,除了最低2位,Ai和Bi已经通过了异或门,因此这个3ty的时间延迟不算,而只用考虑与Ci-1的异或

全先行进位加法器

image-20210928172853824

把C都换掉代入,形成这些式子

Ci-1=1,Pi=1则表示能把这个Ci-1的1传递到Ci

只有Xi和Yi都是1,Gi才为1,Gi表示这位能不能自己生成1

image-20210928173321855

第一步把P和G都计算出,需要1ty

第二步根据式子把C全部计算出,因为式子中只有与和或,因此与可以一起进行,或可以一起进行,所以只要2ty

在第一步和第二步进行的过程中,同时在进行第三步X⊕Y,刚好3ty,因此第一第二和第三步是同时进行的

所以第四步就是进行(X⊕Y)⊕C计算出S,需要3ty

因此总共需要1+2+3=6ty

image-20210928174916195

部分先行进位加法器

image-20210928174424653

每8位用CLA(全先行进位加法器),整体用串行进位加法器,在时间和空间内得到平衡

image-20210928175133879

最后的5是=2+3,第4个CLA要进行第二步2ty和第四步3ty,所以是5ty,当最后一个计算完成时,前面的已经计算完了,所以全部计算好了

image-20211003094155887

两个数加的补码是两个数补码的和

溢出的两种判定:

  1. 加数符号相同而和不同(若符号不同不可能溢出)

  2. Cn异或Cn-1

减法

image-20211003094430337

乘法

image-20211003095101641

计算机只能进行两两相加,因此每一步都把部分积求和

如下图,参与运算的是红色的部分,通过右移保证高4位是参与运算的

image-20211003095842388

image-20211003101651095

刚开始积为n为0,在乘的过程中,部分积的长度会慢慢变长,最终变成2n

但这样的话,2n位的右边n位会空着,会产生浪费,因此把右边n位用来存放乘数Y,这样Y的一位乘完后,右移空出来的位置就可以给积用,如上图,左边一半是乘积寄存器,右边一半是乘数寄存器

加了之后再右移

image-20211003101951588

image-20211003102110215

上面的乘法只适用于原码。

补码不能用于乘法,要用原码去乘,再把积用补码表示,但这样很麻烦,会消耗大量的计算资源

因此出现了布斯乘法,可以用于补码的乘法

布斯乘法

image-20211003102745966

在第四行中,为了保证式子的统一性,引入Y0=0

image-20211003102848122

2的-1次方即右移一位,与原来的乘法不同的地方就在绿色框中,原来是Yi+1,现在是Yi-Yi+1i从0开始,Y0=0),这样,就可以适用于补码的乘法运算了

image-20211003103243188

因为是Yi-Yi+1,相比于原来多了一种可能性**+X,-X,+0**

一共n位,所以要进行n次

image-20211003103612562

因为这里可以处理补码整数,所以会出现负数的情况,如果右移补零那么会无论乘数如何,最后符号位总是0,即总是正数。而对于原来只能处理原码的情况,是不会出现负数的,因此始终是补零

image-20211003104513678

因此在布斯乘法用于处理补码整数乘法时,右移应当是算术右移,符号拓展

image-20211003104844369

除法

image-20211003104912664

image-20211003105359117

补充符号位直到除数最高位和余数的次高位对齐

因此即拓展除数位数长度的符号

要把4位的被除数符号拓展成8位,因为最终结果商应当是4位的

余数实际上是2n位,但只有低n位有用,因此余数只取低n位

image-20211003105722654

恢复余数除法

image-20211003110508948

实际上只有n位参与运算,但为了实现移位操作,用了2n位,因此造成了浪费,同样可以类比乘法来充分利用空间

image-20211003110809081

把除数右移的操作,改成了余数左移的操作,左移右边空出来的就作为商,这样余数同样也只要四位即可

image-20211003110958423

判断够不够减,是根据余数的左边四位来比较的

image-20211003111354476

  • 余数减去除数后,余数符号不发生改变,那么就是够减的

  • 要使得余数的绝对值不断变小,并且符号不改变

image-20211003111751337

image-20211003113300997

最后如果除数和被除数的符号不同,那么要将商变成相反数,即取反加一

没有办法事先去判断够不够减,因此只能运算后看符号有没有变,因此对于机器来说,尝试运算后,发现不够减,那么要恢复余数

当商为4位时,达到所需精度,就运算完成,留下了余数

  • 有没有可能左移的过程中符号变号了,如果有,那么余数的符号到底应该以那个为准**?**

  • 我认为不会移出,如32位cpu中,除数和被除数都是32位,为了得到32位的商,应当把32位被除数符号拓展成64位,而总共运算n=32次,因此不会移出符号位,因此在这个过程中,符号一定不会发生改变,因此发生改变说明不够减,那么需要恢复

不恢复余数的除法

类似开车,当车偏离直线时,不会退回去变成直线,而是往右偏来纠正

image-20211003113412552

  • 乘2是左移

  • 这里的余数Ri是不论是否够减了,都减去Y得到的

  • 只考虑减法(当然有可能是加法,余数和除数异号时):

    • 如果不够减,不需要在上一步进行恢复,而是在下一步通过加Y来同时实现上一步的恢复和这一步的减Y

image-20211218230006824

image-20211003114022720

第一次没有左移,是多一位商放在后面

然后再看余数和除数符号是否相同

同样运算n次

image-20211003114435963

image-20211218231331207

最后还需要对整除可能出现的问题进行判断(原因是如果发生整除,0的符号是0,会产生错误的判断):

  • 如果余数+除数=0,说明多减去一个除数,所以商要-1,余数置0

  • 如果余数=除数,说明少减去一个除数,所以商要+1,余数置0

image-20211003171509243

image-20211003115033240

image-20211003115057588

原码加减法理解

  1. 特点:

    • 符号位不作为数的一部分参与运算
    • 符号位和加减法指令共同作为运算的依据
  2. 规则

    • 加法指令:同号求和,异号求差
    • 减法指令:异号求和,同号求差
  3. 对于求和:

    • 两个操作数相加得到的数值位,如果数值位最高位产生进位,则结果溢出
    • 若不溢出,则和的符号位采用第一操作数的符号
  4. 对于求差:第一操作数的数值位加上第二操作数数值位的补码

    • 最高数值位有进位,表明加法结果为正,结果符号位采用第一操作数的符号

    • 最高数值位没有进位,表明结果为负(补码形式),应对结果求补码,还原成原码形式,结果的符号位为第一操作数的符号取反

    • 理解:事实上,是通过加模再减模(2^k)的方式把减法转成加法,因此如果加后最高位有进位,那么结果减去模就仍然是正数,那么直接取n位结果即可,最高位的进位截断(或者理解为减去了模,因此这个1被减去了)

      如果没有进位,那么说明结果减去模是负数,那么res-2k就不够减,那么就提个负号出来变成-(2k-res),括号里面自然就是取反加1,同时外面的负号用于把第一操作数的符号位取反

  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
  • Copyrights © 2022-2024 zzb
  • RZ
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信