二进制表示的机器数在相对于小数点作n位左移或右移时,其实质就是该数乘以或除以 2n 2 n 。当某计算机没有乘除法运算线路时,可以采用移位和加法相结合,实现乘除运算。
计算机中机器数的字长往往是固定的,当机器数左移n位或右移n位时,必然会使其n位低位或n位高位出现空位。对有符号数的移位称为算数移位。
对于正数,由于 [x]原=[x]补=[x]反= [ x ] 原 = [ x ] 补 = [ x ] 反 = 真值,故移位后出现的空位均以0添之。对于负数,由于原码、补码和反码的表示形式不同,故当机器数移位时,对其空位的填补规则也不同。
不论是整数还是负数,移位后其符号位均不变。
- 机器数为正时,不论是左移还是右移,添补的代码均为0.
- 由于负数的原码数值部分与真值相同,故在移位时只要使符号位不变,其空位均添0即可。
- 由于负数的反码各位除符号位外与负数的原码正好相反,故移位后所舔代码应与原码相反,即全部添1。
- 负数的补码左移时,因空位出现在低位,则添补的代码与原码相同,即添0;右移时因空位出现在高位,则填补的代码应与反码相同,即添1。
对于正数,三种机器数移位后符号位均不变,左移时最高数位丢1,结果出错;右移时最低数位丢1,影响精度。
对于负数,三种机器数算术移位后符号位均不变。负数的原码左移时,高位丢1,结果出错;右移时,低位丢1,影响精度。负数的补码左移时,高位丢0,结果出错;右移时,低位丢1,影响精度。负数的反码左移时,高位丢0,结果出错;右移时,低位丢0,影响精度。
有符号数的移位称为算数移位,无符号数的移位称为逻辑移位。逻辑移位的规则是:逻辑左移时,高位移丢,低位添0;逻辑右移时,低位移丢,高位添0。为了避免算术左移时最高数位丢1,可采用带进位( Cy C y )的移位。算术左移时,符号位移至 Cy C y ,最高数位就可避免移丢。
补码加法的基本公式如下:
整数 [A]补+[B]补=[A+B]补(mod 2n+1) [ A ] 补 + [ B ] 补 = [ A + B ] 补 ( m o d 2 n + 1 )
小数 [A]补+[B]补=[A+B]补(mod 2) [ A ] 补 + [ B ] 补 = [ A + B ] 补 ( m o d 2 )
即补码表示的两个数在进行加法运算时,可以把符号位与数值等同处理,只要结果不超出机器能表示的数值范围,运算后的结果按 2n+1 2 n + 1 取模(对于整数)或按 2 2 取模(对于小数),就能得到本次加法的运算结果。
补码减法的基本公式如下:
整数 [A−B]补=[A]补+[−B]补(mod 2n+1) [ A − B ] 补 = [ A ] 补 + [ − B ] 补 ( m o d 2 n + 1 )
小数 [A−B]补=[A]补+[−B]补(mod 2) [ A − B ] 补 = [ A ] 补 + [ − B ] 补 ( m o d 2 )
而 [−B]补 [ − B ] 补 由 [B]补 [ B ] 补 连同符号位在内,每位取反,末位加1而得。
不论操作数是正还是负,在做补码加减法时,只需将符号位和数值部分一起参加运算,并且将符号位产生的进位自然丢掉即可。
这种超出机器字长的现象叫溢出。为此,在补码定点加减运算过程中,必须对结果是否溢出做出明确的判断。
(1)用一位符号位判断溢出
对于加法,只有在正数加正数和负数加负数两种情况下才可能出现溢出,符号位不同的两个数相加是不会溢出的。
对于减法,只有在正数减负数或负数减正数两种情况下才可能出现溢出,符号位相同的两个数相减是不会溢出的。
只要实际参加操作的两个数符号相同,结果又与原操作数的符号不同,即为溢出。
计算机中采用1位符号位判断时,为了节省时间,通常用符号位产生的进位与最高位有效位产生的进位异或操作后,按其结果进行判断。若异或结果为1,即为溢出;异或结果为0,则无溢出。
(2)用两位符号位判断溢出
2为符号位的补码,即变形补码,它是以4为模的,其定义为
在用变形补码作加法时,2位符号位要连同数值部分一起参加运算,而且高位符号位产生的进位自动丢失,便可得正确结果,即
其中A存放被加数(或被减数)的补码,X存放加数(或减数)的补码。当作减法时,由“求补控制逻辑”将 X¯¯¯¯ X ¯ 送至加法器,并将加法器的最末位外来进位为1,以达到对减数求补的目的。运算结果溢出时,通过溢出判断电路置“1”溢出标记V。 GA G A 为加法标记, GS G S 为减法标记。
两数相乘的过程,可视为加法和移位两种运算。
例:设A=0.1101,B=0.1011,求 A×B A × B 。
运算规则如下:
- 乘法运算可用移位和加法来实现,两个4位数相乘,总共需要4次加法运算和4次移位。
- 由乘数的末尾值确定被乘数是否与原部分积相加,然后右移一位,形成新的部分积;同时乘数也右移一位,由次低位作为新的末位,空出最高位放部分积的最低位。
- 每次作加法时,被乘数仅仅与原部分积的高位相加,其低位被移至成乘数所空出的高位位置。
用一个寄存器存放被乘数,一个寄存器存放乘积的高位,另一个寄存器存放乘数及乘积的低位,再配上加法器及其他相应电路,就可组成乘法器。又因加法志在部分积的高位进行,故不但节省了器材,而且还缩短了运算时间。
上述讨论结果可直接用于原码一位乘,只需加上符号位处理即可。
(1)原码一位乘运算规则
以小数为例:
设 [x]原=x0.x1x2…xn [ x ] 原 = x 0 . x 1 x 2 … x n
[y]原=y0.y1y2…yn [ y ] 原 = y 0 . y 1 y 2 … y n
则 [x]原⋅[y]原=x0⊕y0.(0.x1x2…xn)(0.y1y2…yn) [ x ] 原 ⋅ [ y ] 原 = x 0 ⊕ y 0 . ( 0. x 1 x 2 … x n ) ( 0. y 1 y 2 … y n )
式中, 0.x1x2…xn 0. x 1 x 2 … x n 为x的绝对值,记作 x∗ x ∗ ;; 0.y1y2…yn 0. y 1 y 2 … y n 为y的绝对值,记作 y∗ y ∗ 。
原码一位乘运算规则:
- 乘积的符号位由两原码符号位异或运算结果决定。
- 乘积的数值部分由两数绝对值相乘,其通式为:
x∗⋅y∗=2−1(y1x∗+(…+2−1(yn−1x∗+2−1(ynx∗+0))…)) x ∗ ⋅ y ∗ = 2 − 1 ( y 1 x ∗ + ( … + 2 − 1 ( y n − 1 x ∗ + 2 − 1 ( y n x ∗ + 0 ) ) … ) )
例:已知x=-0.1110,y=-0.1101,求 [x⋅y]原 [ x ⋅ y ] 原 。
故 [x⋅y]原=0.10110110 [ x ⋅ y ] 原 = 0.10110110
注:这里部分积取n+1位,以便存放乘法过程中绝对值大于或等于1的值。此外,由于乘积的数值部分是两数绝对值相乘的结果,故原码一位乘法运算过程中的右移操作均为逻辑右移。
(2)原码一位乘运所需的硬件配置
A、X、Q均为n+1位的寄存器,其中X存放被乘数的原码,Q存放乘数的原码。移位和加控制电路受末尾乘数 Qn Q n 的控制(当 Qn=1 Q n = 1 时,A和X内容相加后,A、Q右移移位;当 Qn=0 Q n = 0 时,只作A、Q右移一位的操作)。计数器C用于控制逐位相乘的次数。S存放乘积的符号。 GM G M 为乘法标记。
(3)原码一位乘控制流程
为了提高乘法速度,可采用原码两位乘。
(4)原码两位乘
原码两位乘是用两位乘数的状态来决定新的部分积如何形成,因此可提高运算速度。
表中3倍被乘数的获得较难。此刻可将3视为4-1,即把乘以3分两步完成:第一步先完成减1倍被乘数的操作,第二步完成加4倍被乘数的操作。而加4倍被乘数的操作实际上是由比“11”高的两位乘数代替完成的,可看作是在高两位乘数上加“1”。这个“1”暂存在 Ci C i 触发器中。机器完成 Ci C i 置“1”,即意味着对高两位乘数加1,也即要求高两位乘数代替本两位乘数“11”来完成加4倍被乘数的操作。
表中z表示原有部分积, x∗ x ∗ 表示被乘数的绝对值, y∗ y ∗ 表示乘数的绝对值,当进行 −x∗ − x ∗ 运算时,一般都采用加 [−x∗]补 [ − x ∗ ] 补 来实现。
为了统一用两位乘数和一位 Ci C i 共同配合管理全部操作,与原码一位乘不同的是,需在乘数(当乘数位数为偶数时)的最高位前增加两个0。当乘数最高两个有效位出现“11”时,需将 Cj C j 置为“1”,再与所添补的两个0结合呈001状态,以完成加 x∗ x ∗ 的操作*(此步不必移位)。
例:设x=0.111111,y=-0.111001,用原码两位乘求 [x⋅y]原 [ x ⋅ y ] 原 。
故 [x⋅y]原=1.111000000111 [ x ⋅ y ] 原 = 1.111000000111
注:当乘数为偶数时,需要做n/2次移位,最多做n/2+1次加法。当乘数为奇数时,乘数高位前可只增加一个"0",此时需做n/2+1次移位(最后一步移一位),最多需做n/2+1次加法。
(1)补码一位乘运算规则
设 [x]补=x0.x1x2…xn [ x ] 补 = x 0 . x 1 x 2 … x n
[y]补=y0.y1y2…yn [ y ] 补 = y 0 . y 1 y 2 … y n
1)被乘数x符号任意,乘数y符号为正
则 [x⋅y]补=[x]补⋅[y]补=[x]补⋅y [ x ⋅ y ] 补 = [ x ] 补 ⋅ [ y ] 补 = [ x ] 补 ⋅ y
当乘数y为正数时,不管被乘数x符号如何,都可按原码乘法的规则运算。
2)被乘数x符号任意,乘数y符号为负
则 [x⋅y]补=[x]补(0.y1y2…yn)+[−x]补 [ x ⋅ y ] 补 = [ x ] 补 ( 0. y 1 y 2 … y n ) + [ − x ] 补
当乘数为负时是把乘数的补码 [y]补 [ y ] 补 去掉符号位,当成一个正数与 [x]补 [ x ] 补 相乘,然后加上 [−x]补 [ − x ] 补 进行校正,也称校正法。
例:已知 [x]补=1.0101 [ x ] 补 = 1.0101 , [y]补=0.1101 [ y ] 补 = 0.1101 ,求 [x⋅y]补 [ x ⋅ y ] 补 。
故乘积 [x⋅y]补=1.01110001 [ x ⋅ y ] 补 = 1.01110001 。
校正法与乘数的符号有关,虽然可将乘数和被乘数互换,使乘数保持正,不必校正,但当两数均为负时必须校正。实现校正法的控制线路比较复杂。若不考虑操作数的符号,用统一的规则进行运算可采用比较法。
3)被乘数x和乘数y符号均为任意
比较法又称Booth算法。
设 [x]补=x0.x1x2…xn [ x ] 补 = x 0 . x 1 x 2 … x n
[y]补=y0.y1y2…yn [ y ] 补 = y 0 . y 1 y 2 … y n
则 [x⋅y]补=[x]补(0.y1y2…yn)−[x]补⋅y0 [ x ⋅ y ] 补 = [ x ] 补 ( 0. y 1 y 2 … y n ) − [ x ] 补 ⋅ y 0
在mod 2的前提下, [−x]补=−[x]补 [ − x ] 补 = − [ x ] 补 成立。
则 [x⋅y]补=[x]补(y12−1+y22−2+…+yn2−n−[x]补⋅y0) [ x ⋅ y ] 补 = [ x ] 补 ( y 1 2 − 1 + y 2 2 − 2 + … + y n 2 − n − [ x ] 补 ⋅ y 0 )
=[x]补[(y1−y0)+(y2−y1)2−1+…+(yn+1−yn)2−n] = [ x ] 补 [ ( y 1 − y 0 ) + ( y 2 − y 1 ) 2 − 1 + … + ( y n + 1 − y n ) 2 − n ]
其中 yn+1=0 y n + 1 = 0 。
开始时 yn+1=0 y n + 1 = 0 ,部分积初值 [z0]补 [ z 0 ] 补 为0,每一步乘法由 (yi+1−yi) ( y i + 1 − y i ) (i=1,2,…,n)决定原部分积加 [x]补 [ x ] 补 或加 [−x]补 [ − x ] 补 或加0,再右移一位得新的部分积,以此重复n步。第n+1步由 (y1−y0) ( y 1 − y 0 ) 决定原部分积加 [x]补 [ x ] 补 或加 [−x]补 [ − x ] 补 或加0,但不移位,即得 [x⋅y]补 [ x ⋅ y ] 补 。
例:已知 [x]补=0.1101 [ x ] 补 = 0.1101 , [y]补=0.1011 [ y ] 补 = 0.1011 ,求 [x⋅y]补 [ x ⋅ y ] 补 。
故 [x⋅y]补=0.10001111 [ x ⋅ y ] 补 = 0.10001111 。
Booth算法的部分积仍取双符号位,乘数因符号位参加运算,故多取1位。
(2)补码比较法(Booth算法)所需的硬件配置
A、X、Q均为n+2位寄存器,其中X存放被乘数的补码(含两位符号位),Q存放乘数的补码(含最高1位符号位和最末1位附加位),移位和加控制逻辑受Q寄存器末2位乘数控制。计数器C用于控制逐位相乘的次数, GM G M 为乘法标记。
(3)补码比较法(Booth算法)控制流程
为了提高乘法的运算速度,可采用补码两位乘。
(4)补码两位乘
补码两位乘运算规则是根据补码一位乘的规则,把比较 ynyn+1 y n y n + 1 的状态应执行的操作和比较 yn−1yn y n − 1 y n 的状态应执行的操作合并成一步得出的。
操作数中出现加 2[x]补 2 [ x ] 补 和加 2[−x]补 2 [ − x ] 补 ,故除右移两位的操作外,还有被乘数左移一位的操作;而加 2[x]补 2 [ x ] 补 和加 2[−x]补 2 [ − x ] 补 都可能因溢出而侵占双符号位,故部分积和被乘数采用3为符号位。
例:已知 [x]补=0.0101 [ x ] 补 = 0.0101 , [y]补=1.0101 [ y ] 补 = 1.0101 ,求 [x⋅y]补 [ x ⋅ y ] 补 。
故 [x⋅y]补=1.11001001 [ x ⋅ y ] 补 = 1.11001001 。
与补码一位乘相比,补码两位乘的部分积多取1为符号位(共3位),乘数也多取1为符号位(共2位),这是由于乘数每次右移2位,且用3位判断,故采用双符号位更便于硬件实现。当乘数数值位为偶数时,乘数取2位符号位,共需作n/2次移位,最多作n/2+1次加法,最后一步不移位;当n为奇数时,可补0变为偶数位,以简化逻辑操作。也可对乘数取1位符号位,此时共进行n/2+1次加法运算和n/2+1次移位(最后一步移一位)。
特点可归纳如下:
- 每次上商都是由心算来比较余数(被除数)和除数的大小,确定商为“1”还是为“0”。
- 每做一次减法,总是保持余数不懂,低位补0,再减去右移后的除数。
- 上商的位置不固定。
- 商符单独处理。
上述规则若照搬到计算机里实现有一定困难:
- 机器不能“心算”上商,必须通过比较被除数(或余数)和除数绝对值大小来确定商值。
- 按照每次减法总是保持余数不懂低位补0,再减去右移后的除数这一规则,在要求加法器的位数必须为除数的两倍。
- 笔算求商时是从高位向低位逐位求的,而要求机器把每位商直接写到寄存器的不同位置也是不可取的。
小数定点除法对被除数和除数有一定的约束,即必须满足下列条件:
(1)恢复余数法
特点是:当余数为负时,需加上除数,将其恢复成原来的余数。
例:已知 x=−0.1011 x = − 0.1011 , y=−0.1101 y = − 0.1101 ,求 [xy]原 [ x y ] 原 。
故商值为0.1101,商的符号位为 x0⊕y0=1⊕1=0 x 0 ⊕ y 0 = 1 ⊕ 1 = 0 ,故 [xy]原=0.1101 [ x y ] 原 = 0.1101 。
第一次上的商在商的整数位上,这对小数除法而言,可用它作溢出判断。即当该位为“1”时,表示此除法溢出,不能进行,应由程序进行处理;当该位为“0”时,说明除法合法,可以进行。
在恢复余数法中,每当余数为负时,都需恢复余数,这就延长了机器出发的时间,操作也很不规则,对线路结构不利。加减交替法可克服这些缺点。
(2)加减交替法
加减交替法又称为不恢复余数法,可以认为它是恢复余数法的一种改进算法。
分析原码恢复余数法得知:
- 当余数 Ri>0 R i > 0 时,可上商“1”,再对 Ri R i 左移一位后减除数,即 2Ri−y∗ 2 R i − y ∗ 。
- 当余数 Ri<0 R i < 0 时,可上商“0”,然后先做 Ri+y∗ R i + y ∗ ,即完成恢复余数的运算,再做 2(Ri+y∗)−y∗ 2 ( R i + y ∗ ) − y ∗ ,即 2Ri+y∗ 2 R i + y ∗ 。
故原码恢复余数法可归纳为:
- 当 Ri>0 R i > 0 时,上商“1”,做 2Ri−y∗ 2 R i − y ∗ 的运算。
- 当 Ri<0 R i < 0 时,上商“0”,做 2Ri+y∗ 2 R i + y ∗ 的运算。
例:已知 x=−0.1011 x = − 0.1011 , y=−0.1101 y = − 0.1101 ,求 [xy]原 [ x y ] 原 。
故商值为0.1101,商的符号位为 x0⊕y0=1⊕0=1 x 0 ⊕ y 0 = 1 ⊕ 0 = 1 ,故 [xy]原=1.1101 [ x y ] 原 = 1.1101 。
倘若比例因子选择合恰当,出发结果不溢出,则第一次商肯定是0.如果省去这位商,只需上商n次即可,此时除法运算一开始应将被除数左移一位减去除数,然后再根据余数上商。
操作数也可采用双符号位,此时移位操作可按算术左移处理最高符号位是真正的符号,次高位符号位在移位时被第一数值位占用。
(3)原码加减交替法所需的硬件配置
A、X、Q均为n+1位寄存器,其中A存放被除数的原码,X存放除数的原码。移位和加控制逻辑受Q的末位 Qn Q n ( Qn=1 Q n = 1 作减法, Qn=0 Q n = 0 作加法),计数器C用于控制逐位相除的次数n, GD G D 为除法标记,V为溢出标记,S为商符。
(4)原码加减交替法控制流程
对于整数除法,要求满足以下条件:
(1)补码加减交替法运算规则
补码除法的符号位和数值部分是一起参加运算的。
1.欲确定商值,必须先比较被除数和除数的大小,然后才能求得商值。
比较被除数和除数的大小
- 当被除数与除数同号时,做减法,若得到的余数与除数同号,表示“够减”,否则表示“不够减”。
- 当被除数与除数异号时,做加法,若得到的余数与除数同号,表示“够减”,否则表示“不够减”。
商值的确定
- 如果 [x]补 [ x ] 补 与 [y]补 [ y ] 补 同号,商为正,则“够减”时上商“1”,“不够减”时上商“0”。
- 如果 [x]补 [ x ] 补 与 [y]补 [ y ] 补 异号,商为负,则“够减”时上商“0”,“不够减”时上商“1”。
2.在补码除法中,商符是在求商的过程中自动形成的。
在小数定点除法中,被除数的绝对值必须小于除数的绝对值,否则商大于1而溢出。当 [x]补 [ x ] 补 与 [y]补 [ y ] 补 同号时, [x]补−[y]补 [ x ] 补 − [ y ] 补 所得的余数 [R0]补 [ R 0 ] 补 必与 [y]补 [ y ] 补 异号,上商“0”,恰好与商的符号一致;当 [x]补 [ x ] 补 与 [y]补 [ y ] 补 异号时, [x]补+[y]补 [ x ] 补 + [ y ] 补 所得的余数 [R0]补 [ R 0 ] 补 必与 [y]补 [ y ] 补 同号,上商“1”,这也与商的符号一致。
商的符号还可用来判断商是否溢出。当 [x]补 [ x ] 补 与 [y]补 [ y ] 补 同号时,若 [R0]补 [ R 0 ] 补 与 [y]补 [ y ] 补 同号,上商“1”,即溢出。当 [x]补 [ x ] 补 与 [y]补 [ y ] 补 异号时,若 [R0]补 [ R 0 ] 补 与 [y]补 [ y ] 补 异号,上商“0”,即溢出。
对于小数补码运算,商等于“-1”应该是允许的,但这需要特殊处理。
3.新余数 [Ri+1]补 [ R i + 1 ] 补 的获得方法与原码加减交替法极相似
其算法规则为:
- 当 [Ri]补 [ R i ] 补 与 [y]补 [ y ] 补 同号时,上商“1”,新余数
[Ri+1]补=2[Ri]补−[y]补=2[Ri]补+[−y]补 [ R i + 1 ] 补 = 2 [ R i ] 补 − [ y ] 补 = 2 [ R i ] 补 + [ − y ] 补- 当 [Ri]补 [ R i ] 补 与 [y]补 [ y ] 补 异号时,上商“0”,新余数
[Ri+1]补=2[Ri]补+[y]补 [ R i + 1 ] 补 = 2 [ R i ] 补 + [ y ] 补
如果对商的精度没有特殊要求,一般可采用“末位恒置1”法,这种方法操作简单,易于实现,而且最大误差仅为 2−n 2 − n 。
例:已知 x=0.1001 x = 0.1001 , y=0.1101 y = 0.1101 ,求 [xy]补 [ x y ] 补 。
所以 [xy]补 [ x y ] 补 =0.1011。
可见n位小数补码除法共上商n+1次(末位恒置“1”),第一次可用来判断是否溢出。共移位n次,并用移位次数判断除法是否结束。
(2)补码加减交替法所需的硬件配置
硬件配置基本上与原码的相似,但S触发器可以省掉,因为补码除法的商符在运算中自动形成。此外在寄存器中存放的均为补码。
(3)补码加减交替法的控制流程
补充说明:
- 图中未画出补码除法溢出判断的内容。
- 多做一次加(或减)法,其实z 末位恒置“1”前,只需移位而不必做加(或减)法。
- 与原码除法一样,图中均未指出对0的检测。
- 为了节省时间,上商和移位操作可以同时进行。