计算机组成原理学习之路(二)——运算方法

参考资料:《计算机组成原理》(秦磊华版)

计算机的主要功能就是对数据信息进行加工处理,这种处理可以归结为算术运算和逻辑运算,前者包括加、减、乘、除四则运算,并与数据的编码形式和表达形式(浮点、定点)密切相关;后者是一种无进位的按位运算,相对比较简单。

1 定点补码加减法运算

数据在计算机中是以一定的编码方式表示的,常用的编码有原码、反码、补码和移码。同一种算术运算,使用不同的编码,有不同的运算法则。采用补码数据表示,不仅符号位同数值位一起参加运算,而且还可以把减法变成加法实现,因此基于补码数据表示的定点补码加减法运算具有运算规则简单,易于实现等优点。

1.1 补码加减法运算方法

  1. 补码加法:
    [ x ] 补 + [ y ] 补 = [ x + y ] 补   ( m o d M ) [x]_补 + [y]_补 = [x + y]_补~(mod M) [x]+[y]=[x+y] (modM)

    在以 M 为模时,两个数的补码之和等于两个数之和的补码,即两个用补码表示的数相加,所得结果为补码表示的和,对定点小数和定点整数都适用:对定点小数而言,M = 2;对定点整数而言,M = 2n+1,其中 n 为定点整数位数(不含符号位)。

  2. 补码减法:
    [ x ] 补 − [ y ] 补 = [ x ] 补 + [ − y ] 补 = [ x − y ] 补   ( m o d M ) [x]_补 - [y]_补 = [x]_补 + [-y]_补 = [x - y]_补~(mod M) [x][y]=[x]+[y]=[xy] (modM)

    对定点小数和定点整数都适用:对定点小数而言,M = 2;对定点整数而言,M = 2n+1,其中 n 为定点整数位数(不含符号位)。由补码减法公式可知,在实施补码减法之前需从 [y] 求出 [-y],可采用多种方法实现该操作,最简单的方法是:对 [y] 各位(包括符号位)取反、末位加1,就可以得到 [-y],也可采用同样的方法从 [-y] 求出 [y]

1.2 溢出及检测

运算结果超出数据类型所能表示数据范围的现象称为溢出。运算结果应该为正,但绝对值超过表示范围,导致结果为负,称为正溢,例如两个数相加,运算结果是负数;运算结果为负,但绝对值超过表示范围,导致结果为正,称为负溢,例如两个负数相加,结果是正数。另外,应该特别注意按模丢掉与运算溢出的区别。

由于机器字长是确定的,所以能表示的数据范围也是有限的,溢出现象不可避免。而溢出往往可能导致有效数字丢失或直接导致错误的运算结果,因此对于计算机系统设计者而言,必须解决溢出的判断问题,以便溢出发生时计算机应能做出相应的处理。

有多种方法可以检测出溢出,下面将主要介绍常见的 3 种方法:

  1. 根据操作数和运算结果的符号位是否一致进行检测:只有两个符号相同的数相加时才有可能产生溢出,因此,可根据操作数和运算结果的符号位是否一致进行检测。

  2. 根据运算过程中最高数据位的进位与符号位的进位位是否一致进行检测:当运算过程中最高数据位的进位与符号位进位位不同步产生时就表明运算结果发生了溢出。

  3. 利用变形补码进行检测:所谓变形补码,就是用两个二进制符号位来表示数据的符号位,其余与补码相同。对定点小数而言,采用变形补码后,其模为 4,因此也称为 “模 4 补码”;对整数而言,采用变形补码后,其模为2n+2(n 为整数数值位的位数)。

    采用变形补码后,正数符号以 “00” 表示,负数的符号以 “11” 表示。一般称左边的符号位为第一符号位,右边的符号位为第二符号位。若运算结果的符号位为 “01” 或 “10”,则表明分别产生了上溢和下溢,即运算结果的两个符号位相同时,表示没有溢出,相异时,则表示溢出。

    需注意的是,不论运输结果是否溢出,第一符号位总是与真实结果的符号位一致。

2 定点乘法运算

从计算机硬件角度看,实现乘法运算的方法主要有以下两种:

  1. 以加法器为基础,并配置相应的逻辑功能器件,通过循环累加实现。
  2. 采用阵列硬件直接实现。

2.1 机器数的移位操作(以补码为例)

移位操作是乘法实现过程中的基本操作,常用的移位操作包括逻辑移位与算术移位两种,每种移位操作又可分为左移和右移。

移位类型移位前的数据移位后的数据特点
逻辑左移1110111011011100左边一位移出,右边空出位补 0
逻辑右移1110111001110111右边一位移出,左边空出位补 0
算术左移1110111011011100各位依次左移,右边空出位补0,一次移位相当于乘以2,当符号位改变时表明溢出
算术右移1110111011110111符号位保持不变,其余各位依次右移,最右边一位移出,将符号位复制到左边空出的位,一次移位相当于除以 2

2.2 原码一位乘法器

为此,对手算方法做如下修改,以方便机器实现:

  1. 设初始部分积为 0,每得到一个部分积就与前面的部分积做一次加法运算,即以累加代替所有部分积同时相加,不仅减少了保存部分积所需的寄存器数目,还能避免一次性部分积求和带来的不便。

  2. 用部分积右移代替手算中的位积左移,不仅使部分积的相加运算可固定在同一位置上进行,而且不再需要长度为 2n 位的加法器。

乘法开始前,令部分积的初值 P0 = 0,然后对乘数末位 yn(假设 ∣ y ∣ = 0. y 1 y 2 y 3 … y n |y| = 0.y_1y_2y_3\dots y_n y=0.y1y2y3yn)进行判断以获得位积 y n × x y_n \times x yn×x,并将位积与 P0 相加。然后将 P0 和 y 同步右移一位,得到新的部分积 P1,部分积中右移出的位按序移入到 y 中。重复这个过程 n 次,最后单独处理乘积的符号位。随着 y 的右移,yn 位总是表示乘数将要被判断的那一位。
在这里插入图片描述
从上图可知:

  • 两个 n 位数参加乘法运算要做 n 次加法和移位操作。
  • 用循环累加与移位操作实现乘法运算。

2.3 补码一位乘法器

由于计算机中采用补码数据表示,如果用原码乘法计算两个数的乘积,运算前后要实现补码和原码之间的转换,为减少处理环节,入们提出了补码乘法。

补码一位乘法的运算规则:

  1. 被乘数一般取双符号位参加运算;

  2. 乘数末位增设附加位 yn+1,且初始值为 0;

  3. 利用 yn+1 与 yn 的差别判断各步的具体运算:

    yn+1 - yn操作
    0部分积右移
    1部分积加 [x] 后右移一位
    -1部分积加 [-x] 后右移一位
  4. 按照上述算法进行 n+1 步累加操作,n 步右移操作。

3 定点除法运算

除法运算与乘法运算的处理思想相似,通常是将 n 位数的除操作转换成若干次 “加减及移位” 的循环操作来实现。

3.1 原码一位除法

为便于在计算机上执行除法运算,对手工除法算法进行如下改进:

  1. 通过减法运算比较数的大小,并作为上商的依据,若余数减去除数大于或等于 0 则表示够减,若小于零则表示不够减。

  2. 将每次右移除数改为左移余数,并与上商操作统一起来,使得上商能固定在一个位置上进行。值得注意的是,每左移一次余数,相当于将余数乘以2,在求得 n 位商后,余数 r 也就被左移了 n 次,因此最后正确的余数应为 rn × 2-n

3.1.1 原码恢复余数法

在原码恢复余数法中,比较被除数(余数)与除数的大小是用减法实现的。对原码除法而言,由于操作数以绝对值的形式参与运算,因此,相减结果为正(余数的符号位为 0)说明够减,商上 1;相减结果为负(余数的符号位为 1)说明不够减,商上 0。

由于除法通过减法实现,当商上 1 时,可将比较数据大小时的减法操作与除法操作中的减法操作合并,即商上 1 后继续后面的除法操作。商上 0 时表明不够减,但因比较操作时已经实施了一次减法,因此,需要对执行比较操作后的结果加上除数,即将余数还原成比较操作前的数值,这种方法就称为恢复余数法。

可以看出上述运算过程是一个循环过程:比较 -> 上商(商为 0 时还需要恢复余数)-> 左移 -> 再比较,直到商达到规定的位数为止。一般商的位数与除数的位数相同。

需注意的是,由于可能需要恢复余数,而除法中恢复余数的步数不能在运算前被确定,导致原码恢复余数除法控制复杂。

3.1.2 原码不恢复余数法

不恢复余数法又称加减交替法,是对恢复余数法的改进。不恢复余数法的特点是不够减时不再恢复余数,而根据余数的符号做相应处理就可继续往下运算,因此运算步数固定,控制简单,提高了运算速度。

不恢复余数法的运算规则是:

  • 当余数为正时,商上 1,余数左移一位,减去除数。
  • 当余数为负时,商上 0,余数左移一位,加上除数。

3.2 基于不恢复余数的补码一位除法

对补码除法而言,也要通过比较被除数(余数)与除数的大小来上商,但由于符号位参与运算,因此判断是否够减不能采用原码除法中的方法,需要通过判断余数和除数的符号来确定。

补码不恢复余数法的算法规则如下:

  1. 被除数与除数同号,被除数减去除数;被除数与除数异号,被除数加上除数。

  2. 余数与除数同号,商上 1,余数左移一位减去除数;余数与除数异号,商上 0,余数左移一位加上除数。需注意的是,余数左移加上或减去除数后就得到了新余数。

  3. 重复上一步,若采用 “恒置1” 法,则包括符号位内共重复第 2 步 n 次;若采用校正法,包括符号在内,则应重复第 2 步 n + 1 次(n 为有效数值位的位数)。

    • “恒置1” 法:补码不恢复余数法除法运算是在商的末位 “恒置1” 的条件下所取得的有限位商。当商为负时是反码形式,而所需要的商是补码形式,两者之间相差的就是末位的 1,这样引起的最大误差是 2-n。在对商的精度没有特殊要求的情况下,一般就采用商的末位 “恒置1” 法,这样操作简单,易于实现。

    • 校正法:如果要求进一步提高商的精度,则按上述步骤再多求一位商,然后用校正的办法对商进行处理。在商为负且不能除尽(即余数 ri ≠ 0)的情况下,求出一个全字长的商以后,可在末位加上 1 进行校正。即按上述算法求得商的反码形式后,再加上 2-n,以得到商的补码形式。

      商的校正可根据下面原则进行:

      • 当刚好能除尽时,如果除数为正,则商不必修正;如果除数为负,则商需要校正,即加 2-n
      • 当不能除尽时,如果商为正,则不必修正;如果商为负,则商需要加 2-n 进行修正。
  4. 求得 n 位商后,得到的余数往往是不正确的,正确的余数常需要根据具体情况做适当的处理才能获得,处理方法一般如下:

    • 若商为正,当余数与被除数符号相同,则不需处理;当余数与被除数异号时,则应将余数加上除数进行修正才能获得正确的余数。

    • 若商为负,当余数与被除数同号时,则余数不需处理;当余数与被除数异号时,则余数需要减去除数进行校正。

    余数之所以需校正,是因为补码不恢复余数除法运算过程中先比较后上商的缘故,可见,如果要保存余数必须根据具体情况对余数做相应处理,否则余数不一定正确。

4 浮点运算

4.1 浮点数加减运算

4.1.1使用补码表示阶码和尾数的浮点数的加减运算

设有两个浮点数:
x = 2 m × M x ,     y = 2 n × M y x = 2^m \times M_x,~~~y = 2^n \times M_y x=2m×Mx,   y=2n×My

对 x 与 y 两个数做加减法运算,则有:
x ± y = 2 m × ( M x ± 2 n − m × M y )    ( 当   m ⩾ n   时 ) 或 x ± y = 2 n × ( 2 m − n × M x ± M y )    ( 当   m ⩽ n   时 ) x \pm y = 2^m \times (M_x \pm 2^{n-m} \times M_y) ~~(当~m \geqslant n~时)\\ 或 \\ x \pm y = 2^n \times (2^{m-n} \times M_x \pm M_y) ~~(当~m \leqslant n~时) x±y=2m×(Mx±2nm×My)  ( mn )x±y=2n×(2mn×Mx±My)  ( mn )

运算步骤如下:

  1. 对阶:对阶的原则是小的阶码向大的阶码看齐,这是因为小阶码增大数值时,尾数部分右移舍去的是尾数的低位部分,但如果让大阶码向小的阶码看齐,则尾数部分相应左移,将会丟失尾数的高位部分,导致运算结果的精确度大大降低。

    对阶又包括如下两个步骤:

    1. 求阶差:通过对两个阶码进行减法运算实现,这不仅能知道阶码的大小,还能求出两个阶码的具体差值。

    2. 阶码的调整与尾数的移位,可按下面方式进行:

      • 若 m > n,则将浮点数 y 的尾数右移 m - n 位。

      • 若 m < n,则将浮点数 x 的尾数右移 n - m 位。

  2. 尾数运算:对阶完成后可按照定点数的加减运算法则执行尾数加减操作,注意,对于阶码小的那个浮点数,应该使用对阶后的尾数参加运算。

  3. 结果规格化:结果规格化就是使运算结果成为规格化数,为了运算处理方便,可让尾数的符号位扩展为两位,当尾数运算结果不是 11.0XX…X 或 00.1XX…X 的形式时,则应进行相应的规格化处理:

    • 当尾数双符号位为 01 或 10 时,需要向右规格化,且只需将尾数右移一位,同时将结果的阶码值加 1。

    • 当尾数运算结果为 11.1XX…X 或 00.0XX…X 时需要左移规格化,而且左移次数不固定,与运算结果的形式有关。左规的方法是尾数连同符号位一起左移位,结果的阶码减 1,直到尾数部分出现 11.0 或 00.1 的形式为止。

  4. 舍入:在对阶右移和右移规格化操作时,尾数末尾的几位会超出机器字长而被丢掉,从而产生误差。这时,计算机可以按选定的方式进行舍入操作,常用的舍入方法如下:

    • 末位恒置 1 法:只要因移位而丢失的位中有一位是1,就把运算结果的最低位置 1,而不管最低位原来是 0 还是 1。

    • 0 舍 1 入法:当丢失位数的最高位是 1 时将尾数的末尾加 1。

  5. 溢出判断:由于浮点数中阶码的位数决定数的表示范围,因此对于浮点运算而言,当阶码出现溢出时才表示运算结果溢出,即当阶码的符号位为 01 和 10 时表示运算结果溢出。

4.2 浮点数乘法运算

设有两个浮点数:
x = 2 m × M x ,     y = 2 n × M y x = 2^m \times M_x,~~~y = 2^n \times M_y x=2m×Mx,   y=2n×My

则浮点数的乘法可表示为:
x × y = 2 m + n × ( M x ⋅ M y ) x \times y = 2^{m+n} \times (M_x \cdot M_y) x×y=2m+n×(MxMy)

运算步骤如下:

  1. 阶码相加:两个数的阶码相加可在加法器中完成。阶码和尾数两个部分并行操作时,可另设一个加法器专门实现对阶码的求和;串行操作时,可利用同一加法器分时完成阶码求和、尾数求积的运算,并且先完成阶码求和运算。阶码相加后有可能产生溢出,若发生溢出,相应部件将给出溢出信号,指示计算机做溢出处理。

  2. 尾数相乘:两个运算数的尾数部分相乘就可得到积的尾数。

  3. 结果规格化:当运算结果需要规格化时,就进行规格化操作。规格化及舍入方法与浮点减法处理的方法相同。

对 IEEE 754 浮点数而言,阶码的运算仍然采用移码的运算法则,尾数处理过程中隐藏位要参与运算,并采用 IEEE 754 的规格化和溢出检测与处理方法。需要特别注意的是IEEE754浮点乘法运算中不存在左移规格化操作。

5 逻辑运算

基本的逻辑运算包括:

  1. 逻辑非:逻辑非又称逻辑求反,即对某变量或二进制数的各位求反。
  2. 逻辑乘:逻辑乘又称逻辑与,运算法则是按位与。
  3. 逻辑加:逻辑加又称逻辑或,运算法则是按位或。
  4. 逻辑异:逻辑异也称逻辑异或。
  5. 逻辑移位:包括逻辑左移和逻辑右移。
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值