计算机组成原理(5)——计算机的运算方法

无符号数和有符号数

无符号数

无符号数,即没有符号的数(只有数值部分),在寄存器中的每一位均可用来存放数值,即寄存器的位数就反映了无符号数的表示范围。

而存放有符号数时,则需留出位置存放符号。因此,在机器字长相同时,无符号数与有符号数所对应的数值范围是不同的。以机器字长 16 位为例,无符号数的表示范围为 0 ~ 65535,而有符号数的表示范围为 -32768 ~ 32767(此数据对应补码表示)

有符号数

把符号“数字化”的数称为机器数,而把带“+”或“-”符号的数称为真值。一旦符号数字化后,符号和数值就形成了一种新的编码,这些编码就是原码、补码、反码和移码。

原码表示法

(1)定义

原码是机器数中最简单的一种表示形式,符号位为 0 表示正数,符号位为 1 表示负数,数值位即真值的绝对值,故原码表示又称为带符号的绝对值表示

整数原码的定义为:
[ x ] 原 = { 0 , x 2 n > x ≥ 0 2 n − x 0 ≥ x > − 2 n [x]_{原}=\left\{ \begin{array}{ll} 0,x & 2^n > x \geq 0 \\ 2^n -x & 0 \geq x > -2^n \end{array} \right. [x]={0,x2nx2n>x00x>2n式中, x x x 为真值, n n n 为整数的位数。例如,当 x x x = +1110 时, [ x ] 原 [x]_{原} [x] = 0,1110;当 x x x = -1110 时, [ x ] 原 [x]_{原} [x] = 1,1110 = 2 4 2^4 24 - (-1110)

小数原码定义为:
[ x ] 原 = { x 1 > x ≥ 0 1 − x 0 ≥ x ≥ − 1 [x]_{原}=\left\{ \begin{array}{ll} x & 1 > x \geq 0 \\ 1 -x & 0 \geq x \geq -1 \end{array} \right. [x]={x1x1>x00x1 式中, x x x 为真值。例如,当 x x x = 0.1101时, [ x ] 原 [x]_{原} [x] = 0.1101;当 x x x = -0.1101 时, [ x ] 原 [x]_{原} [x] = 1.1101 = 1 - (-0.1101)

可见 [ + 0 ] 原 [+0]_{原} [+0] 不等于 [ − 0 ] 原 [-0]_{原} [0],即原码中的“零”有两种表示形式

原码表示简单明了,并易于和真值进行转换。但是用原码进行加法运算时,如果两个操作数符号不同,先要判断两个数绝对值大小,然后将绝对值大的数减去绝对值小的数,结果的符号以绝对值大的数为准。运算步骤既复杂又费时,而且本来是加法运算却要用到减法器实现。

那么能否在计算机中只设加法器,只做加法操作呢如果能找到一个与负数等价的正数来代替该负数,就可把减法操作用加法代替。而机器使用补码时,就能满足此要求

补码表示法

(1)补数的概念

在日常生活中,常会遇到“补数”的概念。例如,时钟指示 6 点,欲使它指示 3 点,既可将分针顺时针转 9 圈,又可将分针逆时针转 3 圈。由于时钟的时针转一圈能指示 12 个小时,这样,-3 和 +9 对时钟而言其作用是一样的。在数学中,称 12 为模,写作 mod 12,而称 +9 是 -3 以 12 为模的补数,记作 -3 ≡ \equiv +9 (mod 12)

可以得到以下结论:

  • 只要确定了 “模”,就可找到一个与负数等价的正数来代替此负数,该正数即为负数的补数,这个正补数可以用模加上负数本身求得
  • 正数的补数就是该正数本身。
  • 一个正数和一个负数互为补数时,它们绝对值之和即为模数。

将补数的概念用到计算机中,便出现了补码这种机器数.

(2)补码的定义

整数补码的定义为:
[ x ] 补 = { 0 , x 2 n > x ≥ 0 2 n + 1 + x 0 > x ≥ − 2 n   ( m o d   2 n + 1 ) [x]_{补}=\left\{ \begin{array}{ll} 0,x & 2^n > x \geq 0 \\ 2^{n+1} + x & 0 > x \geq -2^n\ (mod\ 2^{n+1}) \end{array} \right. [x]={0,x2n+1+x2n>x00>x2n (mod 2n+1) 式中, x x x 为真值, n n n 为整数的位数。即正数的原码和补码相同。当 x x x = -1101 时, [ x ] 补 [x]_{补} [x] = 1,0011 = 2 n + 1 2^{n+1} 2n+1 + (-1101) = 100000 - 1101。

小数补码的定义:
[ x ] 补 = { x 1 > x ≥ 0 2 + x 0 > x ≥ − 1   ( m o d   2 ) [x]_{补}=\left\{ \begin{array}{ll} x & 1 > x \geq 0 \\ 2 + x & 0 > x \geq -1\ (mod\ 2) \end{array} \right. [x]={x2+x1>x00>x1 (mod 2) 式中, x x x 为真值。例如,当 x x x = -0.0110 时, [ x ] 补 [x]_{补} [x] = 1.1010 = 2 + x = 10.0000 - 0.0110

显然,补码中的“零”只有一种表示形式。引入补码的概念是为了消除采用原码所需的减法运算,但是根据补码的定义,在形成补码的过程中又出现了减法(求负数的补码时)。所以一般采用下面的方式来求补码

(3)求补码的快捷方式

正数的补码和原码相同。
当真值为负时,补码可用原码除符号位外每位取反,末位加 1 求得。

反码表示法

反码通常同来作为由原码求补码或者由补码求原码的中间过渡。反码的定义如下:

整数反码定义为:
[ x ] 反 = { 0 , x 2 n > x ≥ 0 ( 2 n + 1 − 1 ) + x 0 ≥ x > − 2 n   ( m o d ( 2 n + 1 − 1 ) ) [x]_{反}=\left\{ \begin{array}{ll} 0,x & 2^n > x \geq 0 \\ (2^{n+1}-1) + x & 0 \geq x > -2^n\ (mod(2^{n+1}-1)) \end{array} \right. [x]={0,x(2n+11)+x2n>x00x>2n (mod(2n+11)) 式中, x x x 为真值, n n n 为整数的位数。例如, x x x = +1101 时, [ x ] 反 [x]_{反} [x] = 0,1101; x x x = -1101 时, [ x ] 反 [x]_{反} [x] = 1,0010

小数反码定义为:
[ x ] 反 = { x 1 > x ≥ 0 ( 2 − 2 − n ) + x 0 ≥ x > − 2 n   ( m o d ( 2 − 2 − n ) ) [x]_{反}=\left\{ \begin{array}{ll} x & 1 > x \geq 0 \\ (2-2^{-n}) + x & 0 \geq x > -2^n\ (mod(2-2^{-n})) \end{array} \right. [x]={x(22n)+x1>x00x>2n (mod(22n)) 式中, x x x 为真值, n n n 为小数的位数。例如, x x x = + 0.0110, [ x ] 反 [x]_{反} [x] = 0.0110; x x x = -0.0110, [ x ] 反 [x]_{反} [x] = ( 2 − 2 − 4 2-2^{-4} 224) + x x x = 1.1111 - 0.0110 = 1.1001

可见,反码中的“零”也有两种表示形式

综上所述,三种机器数的特点可归纳如下:

  • 三种机器数的最高位均为符号位。符号位和数值部分之间可用 ‘.’(对于小数) 或 ‘,’(对于整数)隔开。
  • 当真值为正时,原码、补码和反码的表示形式均相同,即符号位用 “0” 表示,数值部分与真值相同。
  • 当真值为负时,原码、补码和反码的表示形式不同,但其符号位都用“1”表示,而数值部分有这样的关系,即补码是原码除符号位外每位取反末位加 1,反码是原码除符号位外每位取反。

移码表示法

当真值用补码表示时,由于符号位和数值部分一起编码,与习惯上的表示法不同,因此人们很难从补码的形式上直接判断其真值的大小。例如,十进制数 21 的补码为 0,10101,-21 的补码为 1,01011,上述补码中的 “,” 在计算机内部是不存在的,因此,从代码形式看,符号位也是一位二进制数,按这 6 位二进制代码比较大小的话,会得出 101011 > 010101,其实恰恰相反!
在这里插入图片描述

如果对每个真值 加上 2 n 2^n 2n n n n 为整数的位数),情况就发生了变化。还是上面的例子, x x x = 10101 加上 2 5 2^5 25 可得 10101 + 100000 = 110101 x x x = -10101 + 100000 = 001011,比较它们的结果可见 110101 > 001011,这样一来,从 6 位代码本身就可以看出真值的实际大小。由此可得移码的定义为:
[ x ] 移 = 2 n + x   ( 2 n > x ≥ − 2 n ) [x]_{移} = 2^n+x\ (2^n > x \geq -2^n) [x]=2n+x (2n>x2n) 式中, x x x 为真值, n n n 为整数的位数。

用移码判断大小符合人们的习惯,所以浮点数的阶码常用移码表示。

通过观察发现,同一个真值的移码和补码仅差一个符号位。所以移码和补码仅仅是符号位不同,且移码便于直接比较大小(注意正数的移码也不再等于原码、反码和补码)。而且移码中的“零”只有一种表示形式

数的定点表示和浮点表示

在计算机中,小数点不用专门的器件表示,而是按约定的方式标出,共有两种方法表示小数点的存在,即定点表示和浮点表示。

定点表示

小数点固定在某一位置的数为定点数,在计算机中,通常将数据的小数点固定在数据的最高位之前或者最低位之后。前者称为定点小数(纯小数),后者称为定点整数

  • 定点小数是纯小数,约定的小数点位置在符号位之后、有效数值部分最高位之前。若数据 x x x 的形式为 x = x 0 . x 1 x 2 … x n x = x_0.x_1x_2…x_n x=x0.x1x2xn(其中 x 0 x_0 x0 为符号位, x 1 x_1 x1 x n x_n xn 是数值的有效部分,也称为尾数, x 1 x_1 x1为最高有效位)
  • 定点整数是纯整数,约定的小数点位置在有效数值部分最低位之后。若数据 x x x 的形式为 x = x 0 x 1 x 2 … x n x = x_0x_1x_2…x_n x=x0x1x2xn(其中 x 0 x_0 x0 为符号位, x 1 x_1 x1 x n x_n xn 是数值部分, x n x_n xn 为最低有效位)

采用定点数的机器称为定点机,在定点机中,由于小数点的位置固定不变,对于既有整数又有小数的原始数据(即不是纯小数或纯整数时),需要设定一个比例因子,数据按其缩小成纯小数或扩大成纯整数再参加运算,运算结果,根据比例因子,还原成实际数值。若比例因子选择不当,往往会使运算结果产生溢出或降低数据的有效精度。

定点数表示法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大或特别小的数,但均可用浮点数表示!

浮点表示

浮点数即小数点的位置可以浮动的数,这种表达方式利用科学计数法来表达实数,例如 352.47 = 3.5247 * 1 0 2 10^2 102 = 3524.7 * 1 0 − 1 10^{-1} 101 = 0.35247 × 1 0 3 10^{3} 103。通常,浮点数被表示成:
N = S × r j N=S × r^j N=S×rj 式中, S S S 为尾数(可正可负), j j j 为阶码(可正可负), r r r 是基数(基值)。在计算机中,基数可取 2,4,8,16 等。

以基数为 2 为例,数 N N N 可写成下列不同的形式: N = 11.0101 = 0.110101 × 2 10 = 1.10101 × 2 1 = 1101.01 × 2 − 10 = 0.00110101 × 2 100 N = 11.0101=0.110101 × 2^{10}=1.10101 × 2^{1}=1101.01 × 2^{-10}=0.00110101 × 2^{100} N=11.0101=0.110101×210=1.10101×21=1101.01×210=0.00110101×2100

为了提高数据精度以及便于浮点数的比较,在计算机中规定浮点数的尾数用纯小数表示,故上例中的 0.110101 × 2 10 0.110101 × 2^{10} 0.110101×210 0.00110101 × 2 100 0.00110101 × 2^{100} 0.00110101×2100 是可以采用的。此外,将尾数最高位为 1 的浮点数称为规格化数,即 0.110101 × 2 10 0.110101 × 2^{10} 0.110101×210 为浮点数的规格化形式。浮点数表示成规格化形式后,其精度最高

(1)浮点数的表示形式

在这里插入图片描述

浮点数由阶码 j j j 和尾数 S S S 及其符号位组成。阶码是整数,阶符和阶码的位数 m m m 合起来反映浮点数的表示范围及小数点的实际位置;尾数是小数,其位数 n n n 反映了浮点数的精度;数符 S f S_f Sf 代表浮点数的正负。

(2)浮点数的表示范围

在这里插入图片描述

以通式 N = S × r j N=S × r^j N=S×rj 为例,设浮点数阶码的数值位取 m m m 位,尾数的数值位取 n n n 位,当浮点数可为非规格化数时,它在数轴上的表示范围如上图所示。

由图可见,其最大正数为 2 ( 2 m − 1 ) × ( 1 − 2 − n ) 2^{(2^m-1)} × (1-2^{-n}) 2(2m1)×(12n);最小正数为 2 − ( 2 m − 1 ) × 2 − n 2^{-(2^m-1)} × 2^{-n} 2(2m1)×2n;最大负数为 − 2 − ( 2 m − 1 ) × 2 − n -2^{-(2^m-1)} × 2^{-n} 2(2m1)×2n;最小负数为 − 2 ( 2 m − 1 ) × ( 1 − 2 − n ) -2^{(2^m-1)} × (1-2^{-n}) 2(2m1)×(12n)。当浮点数阶码大于最大阶码时,称为上溢,此时机器停止运算,进行中断溢出处理;当浮点数阶码小于最小阶码时,称为下溢,此时溢出的数绝对值很小,通常将尾数各位强置为 0,按机器零处理,此时机器可以继续运行。

一旦浮点数的位数确定后,合理分配阶码和尾数的位置,直接影响浮点数的表示范围和精度。

(3)浮点数的规格化

若不对浮点数的表示作出明确规定,同一个浮点数的表示就不是唯一的。而且为了提高浮点数的精度,其尾数必须为规格化数。如果不是规格化数,就要通过修改阶码并同时左右移尾数的方法,使其变成规格化数,此过程称为规格化。

对于基数不同的浮点数,因其规格化数的形式不同,规格化过程也不同。

  • 基数为 2 时,尾数最高位为 1 的数为规格化数。规格化时,尾数左移一位,阶码减 1(左规);尾数右移一位,阶码加 1(右规)。
  • 基数为 4 时,尾数最高两位不全为零的数为规格化数。规格化时,尾数左移两位,阶码减 1;尾数右移两位,阶码加 1。
  • 基数为 8 时,尾数最高三位不全为零的数为规格化时。规格化时,尾数左移三位,阶码减 1;尾数右移三位,阶码加 1。

浮点机中一旦基数确定后就不再变了,而且基数是隐含的,故不同基数的浮点数表示形式完全相同。但基数不同,对数的表示范围和精度都有影响

定点数和浮点数的比较

① 当浮点机和定点机中数的位数相同时,浮点数的表示范围比定点数的大得多。
② 当浮点数为规格化数时,其相对精度比定点数高。
③ 浮点数运算要分阶码和尾数部分,而且运算结果都要求规格化,故浮点运算步骤比定点运算步骤多,运算速度比定点运算的低,运算线路比定点运算的复杂。
④ 在溢出的判断方法上,浮点数是对规格化数的阶码进行判断,而定点数是对数值本身进行判断。

IEEE 754 标准

现代计算机中,浮点数一般采用 IEEE 指定的国际标准,这种表示形式如下:

在这里插入图片描述

(1) S S S 为数符,它表示浮点数的正负,但与其有效位(尾数)是分开的。

(2)阶码 E E E 用移码表示,基数固定为 2。阶码的真值都被加上一个常数(偏移量,参考移码的定义)。

(3)尾数 M M M 用原码,且隐藏尾数最高位 1。为了提高精度,尾数部分通常都是规格化表示,尾数的最高位始终是1,因此我们完全可以省略掉该位。

常用的浮点数包括 32 位和 64 位:

符号位 S S S阶码 E E E尾数 M M M总位数
32 位182332
64 位1115264

所以,一个规格化 32 位浮点数 x x x 的真值为:
x = ( − 1 ) S ∗ 2 E − 127 ∗ ( 1. M ) x = (-1)^S * 2^{E-127} * (1.M) x=(1)S2E127(1.M) 一个规格化 64 位浮点数 x x x 的真值为:
x = ( − 1 ) S ∗ 2 E − 1023 ∗ ( 1. M ) x = (-1)^S * 2^{E-1023} * (1.M) x=(1)S2E1023(1.M)

定点运算

移位运算

(1)移位运算的数学意义

计算机中小数点的位置是事先约定的,因此,二进制表示的机器数在相对于小数点作 n n n 位左移或右移时,其实质就是该数乘以或除以 2 n 2^n 2n

移位运算称为移位操作,对计算机来说,有很大的实用价值。例如,当某计算机没有乘除法运算线路时,可以采用移位和加法结相结合的方式,实现乘(除)运算

(2)算数移位规则

计算机中机器数的长度往往是固定的,当机器数左移 n n n 位或右移 n n n 位时,必然会使其 n n n 位低位或 n n n 位高位出现空位。那么,对空出的空位应该添补 0 还是 1 呢?这与机器数采用有符号数还是无符号数有关。

无符号数的移位称为逻辑移位,逻辑左移和逻辑右移后出现的空位均以 0 添补

有符号数的移位称为算术移位:对于正数,由于 [ x ] 原 = [ x ] 反 = [ x ] 补 = 真 值 [x]_{原}=[x]_{反}=[x]_{补}=真值 [x]=[x]=[x]=,故移位后出现的空位均以 0 添补;对于负数,由于原码、补码和反码的表示形式不同,所以移位时的添补规则也不同。必须注意的是:算术移位中不论是正数还是负数,移位后的符号位均不变,移的是数值部分,补的也是数值部分,这是算术移位的重要特点

真值码制添补代码
正数原码、补码、反码0
负数原码0
补码左移添 0
右移添 1
反码1

由上表可以得到如下结论:
机器数为正时,无论是左移还是右移,添补代码均为 0;
由于负数的原码数值部分与真值相等,故在移位时只要使符号位不变,其空位均添 0 即可;
由于负数的反码各位除符号位外与负数的原码正好相反,故移位后所添的代码应与原码相反,即全部添 1;
负数的补码左移时,因空位出现在低位,则添补的代码与原码相同,即添 0;右移时因空位出现在高位,则添补的代码应与反码相同,即添 1(也可以理解为补码算数右移时,添补的与符号位相同)。

加法和减法运算

现代计算机中都采用补码作加减法运算

原因如下:

若计算机采用原码计算,在进行加法时,如果两个数符号不同,先要判断两个数绝对值大小,然后将绝对值大的数减去绝对值小的数,结果的符号以绝对值大的数为准,这样运算步骤既复杂又费时,而且本来是加法运算却要用到减法器实现;在进行减法时,虽然可以把减法转换为加法来做,但还是避免不了两个符号不同的数相加的情况,避免不了用到减法器如果能找到一个与负数等价的正数来代替该负数,就可把需减法器做的减法操作用加法代替。而机器使用补码时就能满足此要求,因为补码的思想就是将负数用一个等价的正数来代替

(1)补码加减法运算的公式

补码加法的基本公式如下:

整数 [ A ] 补 + [ B ] 补 = [ A + B ] 补   ( m o d   2 n + 1 ) [A]_{补} + [B]_{补}=[A+B]_{补} \ (mod\ 2^{n+1}) [A]+[B]=[A+B] (mod 2n+1)
小数 [ A ] 补 + [ B ] 补 = [ A + B ] 补   ( m o d   2 ) [A]_{补} + [B]_{补}=[A+B]_{补} \ (mod\ 2) [A]+[B]=[A+B] (mod 2)

由于 A − B = A + ( − B ) A-B=A+(-B) AB=A+(B),所以补码减法的基本公式如下:

整数 [ A − B ] 补 = [ A + ( − B ) ] 补 = [ A ] 补 + [ − B ] 补   ( m o d   2 n + 1 ) [A-B]_{补}=[A+(-B)]_{补}=[A]_{补} + [-B]_{补}\ (mod\ 2^{n+1}) [AB]=[A+(B)]=[A]+[B] (mod 2n+1)
小数 [ A − B ] 补 = [ A + ( − B ) ] 补 = [ A ] 补 + [ − B ] 补   ( m o d   2 ) [A-B]_{补}=[A+(-B)]_{补}=[A]_{补} + [-B]_{补}\ (mod\ 2) [AB]=[A+(B)]=[A]+[B] (mod 2)

用补码表示的两个数在进行加减法运算时,连同符号位一起相加,符号位产生的进位自然丢掉

[ − B ] 补 [-B]_{补} [B] [ B ] 补 [B]_{补} [B] 连同符号位在内,每位取反,末位加 1 而得。

例1:设 A = 0.1011 , B = − 0.0101 A=0.1011,B=-0.0101 A=0.1011,B=0.0101,求 [ A + B ] 补 [A+B]_{补} [A+B]

在这里插入图片描述

按模 2 的意义,最左边的 1 丢掉,故 [ A + B ] 补 = 0.0110 [A+B]_{补}=0.0110 [A+B]=0.0110

例2:设 A = − 1001 , B = − 0101 A=-1001,B=-0101 A=1001,B=0101,求 [ A + B ] 补 [A+B]_{补} [A+B]

在这里插入图片描述

按模 2 4 + 1 2^{4+1} 24+1 的意义,最左边的 1 丢掉。

例3:设机器字长为 8 位(含 1 位符号位),若 A = + 15 , B = + 24 A=+15,B=+24 A=+15,B=+24,求 [ A − B ] 补 [A-B]_{补} [AB]并还原成真值。
在这里插入图片描述

由补码求原码时,根据“补码的补码就是原码”。

可见,不论操作数是正还是负,在做补码加减法时,只需将符号位和数值部分一起参加运算,并且将符号位产生的进位自然丢掉即可。

(2)溢出判断

例4:设机器字长为 8 位(含 1 位符号位),若 A = − 93 , B = + 45 A=-93,B=+45 A=93,B=+45,求 [ A − B ] 补 [A-B]_{补} [AB]
[ A − B ] 补 = 0 , 01110110 [A-B]_{补}=0,01110110 [AB]=0,01110110(结果补码的符号位与A和(-B)补码的符号位不同),还原成真值得 A − B = 118 A-B=118 AB=118,结果出错。这是因为 A − B = − 138 A-B=-138 AB=138 超出了机器字长所能表示的范围。在计算机中,这种超出机器字长的现象叫溢出

补码顶点加减运算判断溢出有两种方法:

  • 一位符号位判断溢出
    实际进行加法操作的两个数(减法时即为被减数和“求补”后的减数)符号相同,其结果的符号与原操作数的符号不同,即为溢出

    对于加法,只有在正数加正数、负数加负数的情况下可能出现溢出,符号不同的两个数是不会溢出的。
    对于减法,只有在正数减负数(相当于正数加正数),负数减正数(相当于负数加负数)这两种情况下才可能出现溢出,符号相同的两个数相减(等同于符号不同的两个数相加)是不会溢出的。

  • 两位符号位判断溢出

    使用双符号位,两个符号位均与单符号位时的相同。做加法时,2 位符号位要连同数值部分一起参加运算,而且高位符号位产生的进位自动丢失,便可得正确结果。当结果的两个符号位不同时,表示溢出,否则无溢出不论是否发生溢出,高位(第一位)符号位永远代表真正的符号

    这里需要说明一点,采用双符号位方案时,寄存器或主存中的操作数只需保存一位符号位即可,因为任何正确的数,两个符号位的值是相同的;而双符号位在加法器中又是必要的,故在相加时,寄存器中一位符号的值要同时送到加法器的两位符号位的输入端。

乘法运算

(1)笔算乘法的改进

若计算机完全模范笔算乘法步骤,将会有两大困难:其一,将多个位积一次相加,机器难以实现;其二,乘积位数增长了一倍,这将造成器材的浪费和运算时间的增加。因此,对笔算乘法进行改进。

在这里插入图片描述

如上图所示,两数相乘的过程,可视为加法和移位(乘 2 − 1 2^{-1} 21相当于做一位右移)两种运算,这对计算机来说是非常容易实现的。
在这里插入图片描述

上述过程过程可归纳如下:
乘法运算可用移位和加法来实现,两个四位数相乘,总共需要进行 4 次加法运算和 4 次移位。
乘数的末位值确定被乘数是否与原部分积相加,然后右移一位,形成新的部分积;同时乘数也要右移一位,由次低位作新的末位,空出最高位放部分积的最低位(如上图乘数中黑色部分所示)。
每次做加法时,被乘数仅仅与原部分积的高位相加,其低位被移至乘数所空出的高位位置。

计算机很容易实现这种运算规则,利用 3 个寄存器(2 个具有移位功能)和一个全加器。用一个寄存器存放被乘数,一个寄存器存放部分积的高位,另一个寄存器存放乘数及部分积的低位,再配上加法器及其他相应电路,就可组成乘法器。又因加法只在部分积的高位运行,故不但节省了器材,而且缩短了运算时间。

(2)原码一位乘法

由于原码的表示与真值极为相似,只差一个符号,而乘积的符号又可通过两数符号的逻辑异或求得,因此,上述讨论的结果可以直接用于原码一位乘,只需加上符号位处理即可。

以小数为例,设 [ x ] 原 = x 0 . x 1 … x n = x 0 . x ∗ , y 原 = y 0 . y 1 … y n = y 0 . y ∗ [x]_{原}=x_0.x_1…x_n=x_0.x^*,y_{原}=y_0.y_1…y_n=y_0.y^* [x]=x0.x1xn=x0.x,y=y0.y1yn=y0.y原码一位乘运算规则如下:
① 乘积的符号位由两原码符号位异或运算结果决定;
② 乘积的数值部分由两数绝对值相乘,同样使用移位的次数来判断乘法是否结束其通式为(小数为例,整数的类似):
在这里插入图片描述

由于乘积的数值部分是两数绝对值相乘的结果,故原码一位乘法运算过程中的右移操作均为逻辑右移

:已知 x = − 0.1110 , y = − 0.1101 x=-0.1110,y=-0.1101 x=0.1110,y=0.1101,求 [ x ⋅ y ] 原 [x \cdot y]_{原} [xy]

[ x ] 原 = 1.1110 [x]_{原}=1.1110 [x]=1.1110 x x x 的绝对值 x ∗ = 0.1110 x^*=0.1110 x=0.1110,其符号位 x 0 = 1 x_0=1 x0=1 [ y ] 原 = 1.1101 [y]_{原}=1.1101 [y]=1.1101 y y y 的绝对值 y ∗ = 0.1101 y^*=0.1101 y=0.1101,其符号位 y 0 = 1 y_0=1 y0=1
按原码一位乘法运算规则, [ x ⋅ y ] 原 [x \cdot y]_{原} [xy] 的符号位为 x 0 ⊕ y 0 = 1 ⊕ 1 = 0 x_0 \oplus y_0=1\oplus 1=0 x0y0=11=0 [ x ⋅ y ] 原 [x \cdot y]_{原} [xy] 的数值部分 x ∗ ⋅ y ∗ x^* \cdot y^* xy 如下表所示。
在这里插入图片描述

[ x ⋅ y ] 原 = 0.10110110 [x \cdot y]_{原}=0.10110110 [xy]=0.10110110 。由上面的例子可知,在进行原码一位乘时,无需在意中间加法过程中发生“溢出”,因为在原码一位乘中,是将数值部分的绝对值相乘,所以根本没有符号位的概念,就算两个以 0 开头的数相加之后的最高位是 1,但逻辑右移后又会变为 0。

(3)补码一位乘法

以小数为例(整数乘法和小数乘法过程完全相同,用逗号代替小数点即可),设被乘数 [ x ] 补 = x 0 . x 1 x 2 . . . x n [x]_{补}=x_0.x_1x_2...x_n [x]=x0.x1x2...xn [ y ] 补 = y 0 . y 1 y 2 . . . y n [y]_{补}=y_0.y_1y_2...y_n [y]=y0.y1y2...yn

被乘数 x x x 符号任意,乘数 y y y 符号为正 x , y x,y x,y 指的都是真值)

被乘数 [ x ] 补 = x 0 . x 1 x 2 . . . x n [x]_{补}=x_0.x_1x_2...x_n [x]=x0.x1x2...xn
乘数 [ y ] 补 = 0. y 1 y 2 . . . y n = y [y]_{补}=0.y_1y_2...y_n=y [y]=0.y1y2...yn=y
[ x ⋅ y ] 补 = [ x ] 补 ⋅ [ y ] 补 = [ x ] 补 ⋅ y [x\cdot y]_{补}=[x]_{补} \cdot [y]_{补}=[x]_{补} \cdot y [xy]=[x][y]=[x]y

与原码乘类似,但移位补码规则运算,乘积的符号自然形成

被乘数 x x x 符号任意,乘数 y y y 符号为负

被乘数 [ x ] 补 = x 0 . x 1 x 2 . . . x n [x]_{补}=x_0.x_1x_2...x_n [x]=x0.x1x2...xn
乘数 [ y ] 补 = 1. y 1 y 2 . . . y n = 2 + y   ( m o d   2 ) [y]_{补}=1.y_1y_2...y_n=2+y\ (mod\ 2) [y]=1.y1y2...yn=2+y (mod 2)
y = [ y ] 补 − 2 = 1. y 1 y 2 . . . y n − 2 = 0. y 1 y 2 . . . y n − 1 y=[y]_{补}-2=1.y_1y_2...y_n-2=0.y_1y_2...y_n-1 y=[y]2=1.y1y2...yn2=0.y1y2...yn1 x ⋅ y = x ( 0. y 1 y 2 . . . y n − 1 ) = x ( 0. y 1 y 2 . . . y n ) − x x \cdot y=x(0.y_1y_2...y_n-1)=x(0.y_1y_2...y_n)-x xy=x(0.y1y2...yn1)=x(0.y1y2...yn)x
[ x ⋅ y ] 补 = [ x ( 0. y 1 y 2 . . . y n ) ] 补 + [ − x ] 补 [x \cdot y]_{补}=[x(0.y_1y_2...y_n)]_{补}+[-x]_{补} [xy]=[x(0.y1y2...yn)]+[x]

所以,将乘数 [ y ] 补 [y]_{补} [y] 视为一个正数,操作与上面 y y y 符号为正时相同,但最后 [ − x ] 补 [-x]_{补} [x] 校正,乘积的符号位也在运算过程中自然形成

被乘数 x x x 符号任意,乘数 y y y 符号任意

Booth 算法。与将 y y y 分符号讨论的计算方法得区别在于,当运算到最后一步时,乘积不再右移,而是根据 y y y 的符号位与数值部分的最高位 y 0 , y 1 y_0,y_1 y0,y1 仅加或减去或不加不减 [ x ] 补 [x]_{补} [x]

在这里插入图片描述

在这里插入图片描述

在进行补码一位乘时,无论是上面哪一种情况,考虑到运算时可能出现绝对值大于 1 的情况(但此刻并不是溢出),故在进行补码加法运算时,部分积和被乘数取双符号位,且进行算数右移操作时,两个符号位都需要进行右移,添补的位与高位符号位相同。

乘法运算分析

前面的笔算乘法改进、原码一位运算、补码一位运算,在理论和计算方法上是行得通的,但是定点计算完成后,其数值部分的位数都扩展为原来的二倍,所以也根本不会发生溢出或者是精度的丢失。

但现实中的机器是做不到这样的,两个定点数相乘得到的数的位数与两数的位数相同。那么使用这种右移 + 加法的方式进行乘法运算时,若最后截取高 n n n 位则会发生精度的丢失。那么结果位数不变的情况下该如何做呢?此时定点整数则需要左移 + 加法,数值部分由高位向低位逐位运算(即与本节讲的方法恰好相反),如果某一步左移时移出的位为 1,则说明发生了溢出。定点小数还是可以使用这节介绍的右移 + 加法,如果右移时移出的位为 1,则说明发生了精度丢失。

本节内容其实讲到笔算乘法可以改进为移位 + 加法就可以结束了,因为后面都是将一个数的位数扩展为两倍,不会溢出,精度也不会丢失,实际意义根本不大。

除法运算(略)

略。

浮点四则运算

浮点加减运算

设两个浮点数
x = S x ⋅ r j x y = S y ⋅ r j y x=S_x \cdot r^{j_x} \\ y=S_y \cdot r^{j_y} x=Sxrjxy=Syrjy 由于浮点数尾数的小数点均固定在第一数值位前,所以尾数的加减运算规则与定点数的完全相同。但由于其阶码的大小又直接反应尾数有效值小数点的实际位置,因此当两浮点数阶码不等时,因两尾数小数点实际位置不一样,尾数部分无法直接进行加减。为此,浮点数加减运算必须按以下几步进行。
对阶,使两数的小数点位置对齐。
尾数求和,将对阶后的两尾数按定点加减运算规则求和(差)。
规格化,为增加有效数字的位数,提高运算精度,必须将求和(差)后的尾数规格化。
舍入,为提高精度,要考虑尾数右移时丢失的精度值。
溢出判断,即判断结果是否溢出。

(1)对阶

对阶的目的是使两操作数的小数点位置对齐,即使两数的阶码相等。为此,首先要求出阶差,再按小阶向大阶看齐的原则,使阶小的尾数向右移位,每右移一位,阶码加 1,直到两数的阶码相等为止。右移的次数正好等于阶差,尾数右移时可能会发生数码丢失,影响精度

阶差计算公式如下:
在这里插入图片描述

x = 0.1101 ∗ 2 01 , y = ( − 0.1010 ) ∗ 2 11 x=0.1101 * 2^{01},y=(-0.1010) * 2^{11} x=0.1101201,y=(0.1010)211,求 x + y x+y x+y
首先写出 x , y x,y x,y 在计算机中的补码表示, x = 00 , 01 ; 00.1101 , y = 00 , 11 ; 11.1010 x=00,01;00.1101,y=00,11;11.1010 x=00,01;00.1101,y=00,11;11.1010,在进行加法前,必须先对阶,故先求阶差
[ Δ j ] 补 = [ j x ] 补 − [ j y ] 补 = 00 , 01 + 11 , 01 = 11 , 10 [\Delta j]_{补}=[j_x]_{补}-[j_y]_{补}=00,01 + 11,01=11,10 [Δj]=[jx][jy]=00,01+11,01=11,10 Δ j = − 2 \Delta j=-2 Δj=2,表示 x x x 的阶码比 y y y 的小,再按小阶向大阶看齐的原则,将 x x x 的尾数右移 2 位,阶码加 2,得 [ x ] 补 ′ = 00 , 11 ; 00.0011 [x]_{补}^{'}=00,11;00.0011 [x]=00,11;00.0011,对阶完毕。

(2)尾数求和

将对阶后的两个尾数按定点加(减)运算规则进行运算

如上例中的两数对阶后得
[ x ] 补 ′ = 00 , 11 ; 00.0011 [ y ] 补 = 00 , 11 ; 11.0110 [x]_{补}^{'}=00,11;00.0011\\ [y]_{补}=00,11;11.0110 [x]=00,11;00.0011[y]=00,11;11.0110 [ S x + S y ] 补 [S_x+S_y]_{补} [Sx+Sy] 为:

在这里插入图片描述

[ x + y ] 补 = 00 , 11 ; 11 , 1001 [x+y]_{补}=00,11;11,1001 [x+y]=00,11;11,1001,这不是一个规格化数。

(3)规格化

当基值 r = 2 r=2 r=2 时,尾数 S S S 的规格化形式为
1 2 ≤ ∣ S ∣ < 1 \frac{1}{2} \leq |S| < 1 21S<1 其是否为规格化数的判断方法如下:

在这里插入图片描述

对于原码,不论正数还是负数,第一位为 1 则表示规格化数;对于补码,符号位与第一位不同则表示规格化数

但是对于 S < 0 S<0 S<0有两种情况需特殊处理
S = − 1 2 S=-\frac{1}{2} S=21,则 [ S ] 补 = 1.100...0 [S]_{补}=1.100...0 [S]=1.100...0。此时对于真值 − 1 2 -\frac{1}{2} 21 而言它满足规格化数( ∣ S ∣ = 1 2 |S|=\frac{1}{2} S=21),但对于补码的判别方法而言它不是规格化数(此时符号位与第一位相同)。为了便于硬件判断,特别规定 1 2 \frac{1}{2} 21 不是规格化的数(对补码而言)
S = − 1 S=-1 S=1,则 [ S ] 补 = 1.00...0 [S]_{补}=1.00...0 [S]=1.00...0。因小数补码允许表示 -1,特别规定 -1 视为规格化的数(对补码而言)

当尾数求和(差)的结果不是规格化数时,则需规格化,规格化又分为左规右规两种(补码):

  • 左规:当尾数出现 00.0 × × × 00.0××× 00.0××× 11.1 × × × 11.1××× 11.1××× 时,需要左规。尾数左移一位,阶码减 1,直到数符和第一位数不同为止

    如上例中的求和结果 [ x + y ] 补 = 00 , 11 ; 11 , 1001 [x+y]_{补}=00,11;11,1001 [x+y]=00,11;11,1001,不是规格化数,需左规,即将其左移一位,同时阶码减 1,得 [ x + y ] 补 = 00 , 10 ; 11 , 0010 [x+y]_{补}=00,10;11,0010 [x+y]=00,10;11,0010,即 x + y = ( − 0.1110 ∗ 2 10 ) x+y=(-0.1110 * 2^{10}) x+y=(0.1110210)

  • 右规:当尾数出现 01. × × × 01.××× 01.××× 10. × × × 10.××× 10.××× 时,表示尾数溢出,这在定点加减运算中是不允许的,但在浮点运算中这不算溢出,因为可通过右规处理右规时尾数右移一位,阶码加 1

:已知两浮点数 x = 0.1101 ∗ 2 10 , y = 0.1011 ∗ 2 01 x=0.1101 * 2^{10},y=0.1011 * 2^{01} x=0.1101210,y=0.1011201,求 x + y x+y x+y
解: x , y x,y x,y在机器中以补码表示为
[ x ] 补 = 00 , 10 ; 00 , 1101 [ y ] 补 = 00 , 01 ; 00 , 1011 [x]_{补}=00,10;00,1101 \\ [y]_{补}=00,01;00,1011 [x]=00,10;00,1101[y]=00,01;00,1011 ① 对阶
[ Δ j ] 补 = [ j x ] 补 − [ j y ] 补 = 00 , 10 − 00 , 01 = 00 , 01 [\Delta j]_{补}=[j_x]_{补}-[j_y]_{补}=00,10 - 00,01=00,01 [Δj]=[jx][jy]=00,1000,01=00,01 这表明 y y y 的阶码比 x x x 的要小,根据小阶向大阶看齐的原则, y y y 的尾数右移 1 位,阶码加 1,即 [ y ] 补 ′ = 00.10 ; 00.0101 [y]_{补}^{'}=00.10;00.0101 [y]=00.10;00.0101(精度损失)
② 尾数求和
在这里插入图片描述

③ 右规
上面的计算结果为 [ x + y ] 补 = 00 , 10 ; 01 , 0010 [x+y]_{补}=00,10;01,0010 [x+y]=00,10;01,0010
右规后 [ x + y ] 补 = 00 , 11 ; 00 , 1001 [x+y]_{补}=00,11;00,1001 [x+y]=00,11;00,1001(注意连同溢出的符号位一起移位),所以 x + y = 0.1001 ∗ 2 11 x+y=0.1001 *2^{11} x+y=0.1001211

(4)舍入

在对阶和右规过程中,可能出现尾数末位丢失,引起误差。为此可用舍入法来提高尾数的精度,常用的舍入法有以下两种:

  • 0 舍 1 入 法。在尾数右移时,被移去的尾数末位为 0,则舍去;被移去的最高数值位为 1,则在尾数的末位加 1。这样做可能使尾数又溢出,此时需再做一次右规。
  • 恒置 1 法。尾数右移时,不论丢掉的最高数值是 1 还是 0,都使右移后的尾数末尾恒置 “1”。这种方法同样有使尾数变大和变小的两种可能。

综上所述,浮点加减运算经过对阶、尾数求和、规格化和舍入等步骤,与定点加减运算相比,显然要复杂得多。

(5)溢出判断

与定点加减法一样,浮点加减运算最后一步也需判断溢出。在浮点规格化中已指出,当尾数之和(差)出现 01. × × × 01.××× 01.××× 10. × × × 10.××× 10.××× 时,并不表示溢出,只有将此数右规后,再根据阶码来判断浮点数运算结果是否溢出。

阶码 [ j ] 补 = 01. × × × [j]_{补}=01.××× [j]=01.××× 为上溢;阶码 [ j ] 补 = 10. × × × [j]_{补}=10.××× [j]=10.××× 为下溢,按机器零处理。

浮点乘除法运算(略)

略。

算数逻辑单元

针对每一种算术运算,都必须有一个相对应的基本硬件配置,其核心部件是加法器和寄存器。当需要完成逻辑运算时,势必需要配置相应的逻辑电路,而 ALU 电路是既能完成算术运算又能完成逻辑运算的部件。

本BLOG上所有的原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请注明出处,否则属于侵权行为:
https://blog.csdn.net/qq_39583450/article/details/114607570

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值