计算机组成原理第六章 计算机的运算方法

文章目录

[6.1 无符号数和有符号数](#6.1 无符号数和有符号数)

[6.1.1 无符号数](#6.1.1 无符号数)

[6.1.2 有符号数](#6.1.2 有符号数)

1、原码

2、补码

3、反码

4、移码

5、小结

[6.2 数的定点表示和浮点表示](#6.2 数的定点表示和浮点表示)

[6.2.1 定点表示](#6.2.1 定点表示)

[6.2.2 浮点表示](#6.2.2 浮点表示)

1、浮点数的表现形式

2、浮点数的表示范围

3、浮点数的规格化

[6.2.3 定点数和浮点数的比较](#6.2.3 定点数和浮点数的比较)

[6.2.5 IEEE754标准](#6.2.5 IEEE754标准)

[6.3 定点运算](#6.3 定点运算)

[6.3.1 移位运算](#6.3.1 移位运算)

1、定义

2、算数移位规则

3、硬件实现左移和右移

4、算数移位和逻辑移位的区别

[6.3.2 加减法](#6.3.2 加减法)

1、补码加法的基本公式

2、溢出判断

[6.3.3 乘法运算](#6.3.3 乘法运算)

1、笔算乘法

2、原码一位乘运算

3、原码两位乘运算

4、补码一位乘运算

[6.3.4 除法运算](#6.3.4 除法运算)

1、笔算除法分析

2、原码除法

3、补码除法

[6.4 浮点四则运算](#6.4 浮点四则运算)

[6.4.1 浮点加减运算](#6.4.1 浮点加减运算)

1、对阶

2、尾数求和

3、规格化

4、舍入

5、判断溢出

6、完整运算

[6.4.2 浮点乘除运算](#6.4.2 浮点乘除运算)

6.1 无符号数和有符号数

6.1.1 无符号数

1、定义

所谓无符号数即没有符号的数,在寄存器中的每一位均可用来存放数值。

例如 123就是一个 无符号数±123就是一个有 符号数,显然无符号数只能表达正数,不能表达负数。

2、表示范围

无符号的数的表示范围和**机器字长** 有关,如果机器字长为16位,那么无符号数的表示范围就是:0~65535

65535就是 216-1

6.1.2 有符号数

对有符号数而言,++符号的"正"、"负"机器是无法识别的++ ,但由于"正"、"负"恰好是两种截然不同的状态,++如果用"0"表示"正",用"1"表示"负"++,这样符号也被数字化了,并且规定将它放在有效数字的前面,这样就组成了有符号数。

有符号数的表示有三种方式:

  • 原码
  • 补码
  • 反码
1、原码

原码定义如下:

例:如果是整数

1101原 = 0,1101

-1101原 = 1,1101

使用" **,"**作为间隔。

如果是小数

0.1101原 = 0.1101

-0.1101原 = 1.1101

使用" **."**作为间隔, 并且把原先整数位的0改为了符号位

原码中有一个特殊例子,那就是0的原码。

由于0可以表示为﹢0﹣0,所以0的原码有两种:

  • ﹢00,0
  • ﹣01,0

如果机器中采用原码做运算,会出现如下问题:

当一个正数加上一个负数的时候,符号位有可能为正也有可能为负。

相当于做了减法运算,但是计算机不擅长做减法而是擅长加法,所以需要进行一个转换。

为了避免这种情况于是出现了补码

2、补码

补码的本质其实就是**同余**。

举个例子,在时钟 的背景下,如果想要把6点变为3点,有两种做法:

  • 6 - 3 = 3
  • 6 + 9 = 15 = 3

15点相当于3点。

所以这里6加9和减去3的效果是一样的。

补码的定义如下:

有一种更简单的方法求解:

  • 对于正数xx原 = x
  • 对于负数xx补 = x原 符号位不变,各位取反,末位加一

例如:

  • 1101补=1101原 = 0,1101
  • -1101补 = 1,0011

负数求解过程如下:
首先求解原码:- 1101原 = 1,1101
除了符号位 1,后面四位取反:1,0010
最后末位一个数加一1,0011
++如果遇到算数溢出,则舍去溢出部分++

和原码不同的是,±0的补码都是相同的,以4位为例:

  • + 0000补:0,0000
  • - 0000补:0,0000
  • 0000的原码是1,0000
    各位取反为:1,1111
    末尾加1会发现此时变为了10,0000
    ++这里会发现符号位溢出了,需要去掉最高位++ ,所以 [-0000]补:0,0000

最后补充一个知识点:

相反数的补码连同符号位,各位取反,末位加一

假设[y]补 = y0.y1y2...yn,求-y

3、反码

定义:

求解很简单:

  • 正数:等同于原码
  • 负数:符号位不变,各位取反

例如:

  • 1101反=1101原 = 0,1101
  • -1101反 = 1,0010
4、移码

当真值使用补码表示的时候,由于符号位和数值部分一起编码,所以比较的时候很难从补码的形式上判断真实的大小。

例如数21对应二进制的补码就是:0,10101

-21对应二进制的补码表示是:1,01101

由于在计算机中,,其实是不存在的,只是为了便于辨别符号和真值才写的,所以符号位也是一个二进制数 ,从代码形式上来看,就会得出1,01101 > 0,10101

但实际是相反的,为了便于直接进行比较,所以出现了移码

移码的定义是在对应真值加上一个2n。

但是这里有一个更简单的方法计算:对应补码符号位取反

例如:

  • 10101移 = 1,10101
  • -10101移 = 0,01011

这样就可以直接比较移码的大小判断真值的大小。

5、小结

计算机三种码制

正数x原 = x补= x

负数

  • x补 = x原 符号位不变,各位取反,末尾加一
  • x反 = x原 符号位不变,各位取反

正数使用,区分,小数使用.区分。

表示范围:(假设机器字长为8位,总共可以表示256个数)

  • 原码:-127 ~ 127
  • 补码:-128 ~ 127
  • 反码:-127 ~ 127
  • 真值: 0 - 255

6.2 数的定点表示和浮点表示

6.2.1 定点表示

所谓定点表示,就是小数点的位置是固定

当小数点位于++数符和第一数值位之间时,机器内的数为纯小数++;

当小数点++位于数值位之后时,机器内的数为纯整数++。

在定点机中,由于小数点的位置固定不变,故当机器处理的数不是纯小数或纯整数时,必须乘上一个比例因子,否则会产生"溢出"。

比如机器字长为8位,使用定点表示 4这个数就是 0000100
使用定点表示 0.5这个数就是 0.10000000(小数点后面8位)
简单来说 定点数就是保证 位数固定不变

6.2.2 浮点表示

①常用的科学计数法

352.47=3.5247×102

=3524.7×10-1

=0.35247×103

浮点表示也是类似的,其格式如下:

其中:

  • N :真值
  • S :尾数(可正可负)
  • r :基数(一般取 2,4,8)
  • j :阶码(可正可负)

举个例子:

11.0101 = 0.110101 * 210

注意:这里的 10不是十进制当中的十,而是二进制表示的 2

  • S :0.110101
  • r :2
  • j :10
1、浮点数的表现形式

浮点数的表现形式如下:

j位用于表示阶码 ,其中1位表示**阶符** (1表示-0表示+),剩下用于表示真值

s位用于表示尾数 ,其中1位表示数符1表示-0表示+),剩下用于表示真值

举个例子,假设阶码有4位,尾数有8 0.110101 * 210可以表示为:

0,010; 0.1101010

  • 阶符 :0(1位)
  • 阶码真值 :010(3位)
  • 数符 :0(1位)
  • 尾数真值 :.1101010(7位)

使用;间隔尾数和阶码
其中:当小数点后面第一位为1的时候,这种为浮点数的规格化形式。
例如:N = 0.110101 * 210

2、浮点数的表示范围

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

首先看正数区,也就需要求出最大正数最小正数即可确定范围。

如果是最大正数,那么阶码就应该取正数的最大值 ,m位数值为阶码代表阶码数值的最大值应该为2m-1

例如:阶码数值为有4位,那么最大值应该是 1111也就是 15 = 24 -1

其次,尾数 也要最大,++也就是尾数数值部分应该全为1++ ,数值部分总共有n位,那尾数的最大值就是1-2-n

例如:尾数数值有8位,那么最大值应该是 0.11111111也就是 1-2-8

浮点数的数值只有在这两个区间(负数区和正数区)之间是有效的,超出这两个区域的都被称为溢出

  • 上溢出浮点数阶码大于最阶码,机器停止运算,进行中断溢出处理
  • 下溢出:浮点数阶码小于最 阶码,尾数强置 为0,按照机器零处理
3、浮点数的规格化

在浮点数中:基数r越大,表示的浮点数范围越大,但是精度会下降。

为了提高精度,一般会把尾数转为规格化数 ,++通常通过修改阶码并且将尾数左右移动的方式实现++,实现规则如下:

  • 基数为2
    • 尾数最高位为1的数是规格化数
    • 左规:尾数左移1位,阶码减1
    • 右规:尾数右移1位,阶码加1
  • 基数为4
    • 尾数最高2位不全为0的数是规格化数
    • 左规:尾数左移2位,阶码减1
    • 右规:尾数右移2位,阶码加1
  • 基数为8
    • 尾数最高3位不全为0的数是规格化数
    • 左规:尾数左移3位,阶码减1
    • 右规:尾数右移3位,阶码加1

注意这里的左移指的是尾数左移,实际小数点是右移的。
例如:0.0010变为0.0100就是左移1位

  例:将十进制数+13/128写成二进制定点数和浮点数(++数值部分取10位,阶码部分取4位,阶符和数符各取1位++),分别写出它在定点机和浮点机中的机器数形式。

这里只要知道 1/128就是2-7即可,记得知道 +13/128 = 1101 * 2-7

解:令x=+13/128

  其二进制形式:x=0.0001101000

  定点数形式:x=0.0001101000

定点数不足的位数使用0补齐,小数后面补0,整数前面补0。

  浮点数规格化表示:x=0.1101000000×2-11

浮点数的表示可以根据定点数来写, 对定点数进行规格化

  定点机中 x原=x补=x反=0.0001101000

  浮点机中 x原:1,0011;0.1101000000

  x补:1,1101;0.1101000000

6.2.3 定点数和浮点数的比较

(1)++当浮点机和定点机中的数其位数相同时,浮点数的表示范围比定点数大得多++。

(2)当++浮点数为规格化数时,其精度远比定点数高++。

(3)浮点数运算要分阶码部分和尾数部分,而且运算结果都要求规格化 ,故浮点运算步骤比定点运算步骤多,运算速度比定点低,运算线路比定点复杂。

(4)在溢出的判断方法上,浮点数是对规格化数的阶码进行判断,而定点数是对数值本身进行判断。如小数定点机中的数其绝对值必须小于1,否则即"溢出",此时要求机器停止运算,进行处理。为了防止溢出,上机前必须选择比例因子,这个工作比较麻烦,给编程带来不便。而浮点数的表示范围远比定点数大,仅当"上溢"时机器才停止运算,故一般不必考虑比例因子的选择。

6.2.5 IEEE754标准

在IEE754浮点数标准中,定义的浮点数的格式如下表所示。

|------------|-----|-------|--------|--------|
| 浮点数 | 符号位 | 阶码 | 尾数 | 总位数 |
| 短实数长实数临时实数 | 111 | 81125 | 235264 | 326480 |

在IEEE754标准里面:

  • 阶码 使用移码表示
  • 尾数补码表示

这样做的目的是机器零的表示正好 可以让所有的位都是0,便于机器判断。

6.3 定点运算

6.3.1 移位运算

1、定义

举个简单的例子:15m = 1500cm

这就代表了15这个数字左移了2两位,左移之后空缺的地方补上了0,这就是移位运算。

在十进制中,左移一位,相当于数值大小为原来的10倍,那么在二进制中,左移一位,相当于数值大小为原来的2倍。

前面我们知道,++计算机中有些二进制数是代表符号位的++,那么又产生如下定义:

  • 逻辑移位:无符号位进行移位
  • 算数移位:有符号位进行移位
2、算数移位规则

补位的规则如下:

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

在算数移位的过程中:++符号位不参与移动++

举个例子:

设机器数字长为8位(含一位符号位),若A=±26,写出++三种机器数左、右移一位和两位后的表示形式++及对应的真值,并分析结果的正确性。

首先来看正数,根据八位的字长写出其二进制形式0,0011010(左移时最高数位丢1,结果出错,右移时最低数位丢1,影响精度)

|----------------------|-----------|-------|
| 移位操作 | 机 器 数 | 对应的真值 |
| A原=A补=A反 |
| 移位前 | 0,0011010 | +26 |
| 左移一位 | 0,0110100 | +52 |
| 左移两位 | 0,1101000 | +104 |
| 右移一位 | 0,0001101 | +13 |
| 右移两位 | 0,0000110 | +6 |

接下来看负数,这里就需要根据三种码制的不同来分别分析:

|------|-----------|-----------|-----|
| 移位操作 | 机 器 数 | 对应的真值 |
| 移位前 | 原码 | 1,0011010 | -26 |
| 左移一位 | 1,0110100 | -52 |
| 左移两位 | 1,1101000 | -104 |
| 右移一位 | 1,0001101 | -13 |
| 右移两位 | 1,0000110 | -6 |
| 移位前 | 补码 | 1,1100110 | -26 |
| 左移一位 | 1,1001100 | -52 |
| 左移两位 | 1,0011000 | -104 |
| 右移一位 | 1,1110011 | -13 |
| 右移两位 | 1,1111001 | -7 |
| 移位前 | 反码 | 1,1100101 | -26 |
| 左移一位 | 1,1001011 | -52 |
| 左移两位 | 1,0010111 | -104 |
| 右移一位 | 1,1110010 | -13 |
| 右移两位 | 1,1111001 | -6 |

总结上述规律:

  • 左移可能会导致结果出错(最高位丢失)
  • 右移可能会导致结果精度下降(最低位丢失)
3、硬件实现左移和右移

其中(a)真值为正的三种机器数的移位操作;(b)负数原码的移位操作;(c)负数补码的移位操作;(d)负数反码的移位操作。

4、算数移位和逻辑移位的区别

有符号数的移位称为算术移位,无符号数的移位称为逻辑移位。

逻辑移位的规则是:逻辑左移时,高位移出,低位添0;逻辑右移时,低位移出,高位添0。例如,寄存器内容为01010011,逻辑左移为1010010,算术左移为00100110(最高数位"1"移丢)。

又如寄存器内容为10110010,逻辑右移为01011001。若将其视为补码,算术右移为11011001。显然,两种移位的结果是不同的。

上例中为了避免算术左移时最高数位丢1,可采用带进位(Cy)的移位,其示意图如下图所示。算术左移时,符号位移至Cy,最高数位就可避免移出。

6.3.2 加减法

1、补码加法的基本公式

前面说过,计算机通常会把减法化为加法进行计算,而把减法化为加法的做法就是使用补码。

加法公式如下:

  • 整数A补+B补=A+B补 (mod 2n+1)
  • 小数A补+B补=A+B补 (mod 2)

减法公式如下:

  • 整数A-B补=A补+-B补 (mod 2n+1)
  • 小数A-B补=A补+-B补 (mod 2)

例1:x=0.1010,y=-0.0011,用++补码的加法++求x+y

解:x补=0.1010,y补=1.1101

  x补+y补=0.1010+1.1101=10.0111(溢出部分舍去)

  x+y=0.0111

例2:x=0.1001,y=-0.0011,用++补码的减法++求x-y

解:x补=0.1001,y补=1.1101,-y补=0.0011

  x补-y补=x补+-y补=0.1001+0.0011=0.1100

  x-y=0.1100

2、溢出判断

例如在上面的题目中,补码做加减法的时候可能会存在溢出现象,这种溢出判断会影响实际值的大小,也就是超出了机器字长表示的范围。所以需要做溢出判断。

判断方式有两种:

(1)用一位符号做溢出判断

不难知道,只有如下两种情况才可能出现溢出:

  • 正数+正数
  • 负数+负数

减法统一化为加法。

如果出现溢出现象,那么AB两位的符号位应该是相同的,当运算结果的符号位和原AB符号位不同的时候,就是溢出

例如:

(2)用两位符号做溢出判断

原始的符号位定义如下:

  • 正:0
  • 负:1

两位符号位的定义如下:

  • 正:00
  • 负:11

同样,如果出现溢出现象,那么AB两位的符号位应该是相同的。

这种带有两位符号位的补码叫做**变形补码,变形补码的运算需要带上符号位。**

变形补码判断溢出的原则是:运算结果的两位符号位不同的时候,就表示溢出,否则就是不溢出。

  • 溢出:两位符号位为01
  • 溢出:两位符号位为10

无论是否溢出,两位符号位的最高位表示变形补码的真正符号

例:设x=+1100y=+1000,求6位双符号位补码之和x+y补。

x补=00,1100, y补=00,1000

x+y补=00,1100+00,1000=01,0100

x+y补=01,0100,其中两个符号位出现01,表示已溢出,并且为上溢出,最终结果符号为正。

验算可得:x+y = 12 + 8 = 20 ,确实为上溢出。

6.3.3 乘法运算

1、笔算乘法

设A=0.1101,B=0.1011,求A×B。

如果是笔算,可以知道:

可以看的出来,二进制的乘法其实可以概括为两个运算:加法运算移位运算

加法就是加法,而移位运算实际上就是乘2n,将其稍作改动可以获得:

由此可以知道原码的计算乘法的方法,主要有两种方法:

  • 原码一位乘法
  • 原码两位乘法

这里的一位指代的是一次和一位二进制数做运算
那么两位就是指一次和两位二进制数做运算。

2、原码一位乘运算

在计算机中,乘法最后的结果不是有一块单独的寄存器存储的,而是分为两块:ACC(乘积高位),MQ(乘积低位)

①乘法运算可用移位和加法来实现,两个4位数相乘,总共需要进行4次加法运算和4次 移位。

②由乘数的末位值确定被乘数是否与原部分积相加,然后右移一位,形成新的部分积;同时,乘数也右移一位,由次低位作新的末位,空出最高位放部分积的最低位。

③每次做加法时,被乘数仅仅与原部分积的高位相加,其低位被移至乘数所空出的高位位置

步骤如下:

  • 首先,符号位 由乘数和被乘数的符号位做异或决定,不参与后面的真值运算。
  • 高位部分首先置为0,低位部分为乘数真值
  • 然后被乘数依次乘以**乘数各位(从低位到高位),其结果加上前一次高位部分的结果,作为高位的最终结果**
  • 高位部分右移一位,移出的部分补到低位部分的高位,低位部分的最低位舍去(这一点非常重要)
  • 往复上述过程,直到乘数所有位数都被乘完,最终**++高位和低位合并即为最终结果++**。

比如,一开始高位置为0,也就是00.0000,低位为乘数真值,也就是1011

先做加法运算 ,被乘数1101乘以乘数最低位1答案就是1101,结果加上前一次高位就是00.1101

接下来做移位运算 ,高位右移一位:00.01101;低位右移并且补位:11101

3、原码两位乘运算

原码两位乘与原码一位乘一样,符号位的运算和数值部分是分开进行的,但原码两位乘是用两位乘数的状态来决定新的部分积如何形成,因此可提高运算速度

思路还是和一位乘一样,一位乘每次值乘一个二进制位数,也就是只有0, 1,两位乘就有四种情况:

|-----|------------|
| 乘数 | 新的部分积 |
| 0 0 | 加上0倍的|x| |
| 0 1 | 加上1倍的|x| |
| 1 0 | 加上2倍的|x| |
| 1 1 | 加上3倍的|x| |

上面四种情况里面,++0倍就是加上0,1倍就是加上原数,2倍相当于原数直接左移一位++ ,只有3倍处理起来比较麻烦,在计算机中可以这样操作:++原数先乘以4(左移两位),再减去1倍的原数(转为补码就变成了加法)++。

4、补码一位乘运算

6.3.4 除法运算

1、笔算除法分析

笔算除法如下:

和正常十进制的除法运算类似,特点可以归纳为:

  • 每次上商都是通过比较余数(被除数)和除数的大小来确定商为1还是0。
  • 例如:第一步中0.1101作为除数,大于被除数 0.1011,所以第一位上商为0
  • 每一次做减法运算,余数(被除数)不动,低位补0再减去右移后的除数
  • 上商的位置不固定(说实话我也不懂这句话是什么意思)
  • 商符单独处理(也就是做异或运算)

小数定点除法运算对于被除数和除数有一定的约束:0 < |被除数| ≤ |除数|

2、原码除法

原码除法有两种方法:

(1)恢复余数法

特点:当余数为负数的时候,加上除数,让余数恢复为原来的余数。

步骤

  1. 符号位单独按两数符号异或求得;参与运算的是绝对值的补码
  2. 判溢出, 要求|被除数| < |除数| (对小数而言)(如果是整数,则要求|被除数| > |除数| );
  3. 被除数减去除数,(加上除数的补码
  4. ++若所得余数为正,相应位上商为1,余数左移一位,减去y补;若余数为负,相应位上商为0,余数加上除数(恢复余数),再左移一位,加上-y补;++
  5. 重复第4步,直到求得所要求的商为止(移n次)
  6. 若最后一步余数为负,则需要恢复余数。

举个例子:

例:已知:x=-0.1011,y=-0.1101,求:x÷y

解:首先写出x和y的原码补码:[x]原=1.1011[y]补=1.0011,[y]原=1.1101

|------------------------|---------|--------------------------------|
| 被除数(余数) | 商 | 说 明 |
| 0.1011 + 1.0011 | 0.0000 | +-y\*补(减去除数) |
| 1.1110 + 0.1101 | 0 | 余数为负,上商0 恢复余数+y\*补 |
| 0.1011 1.0110 + 1.0011 | 0 | 被恢复的被除数 左移1位 +-y\*补(减去除数) |
| 0.1001 1.0010 + 1.0011 | 01 01 | 余数为正,上商1 左移1位 +-y\*补(减去除数) |
| 0.0101 0.1010 +1.0011 | 011 011 | 余数为正,上商1 左移1位 +-y\*补(减去除数) |
| 1.1101 + 0.1101 | 0110 | 余数为负,上商0 恢复余数+y\*补 |
| 0.1010 1.0100 + 1.0011 | 0110 | 被恢复的被除数 左移1位 +-y\*补(减去除数) |
| 0.0111 | 01101 | 余数为正,上商1 |

符号位由除数和被除数决定,最后可得,商值为0.1101

四位小数,做 五次加法运算,其中最后一次为矫正作用。

(2) 加减交替法

所谓加减交替法,也就是不做余数的回复,通过先移位的方式来避免恢复余数,过程如下:

举个例子:

例:已知:x=-0.1011,y=0.1101,求:x÷y

解:首先写出x和y的原码补码:[x]原=1.1011[-y]补=1.0011,[y]原=1.1101

这里是无论上商为多少,都是先做移位运算,再根据上商做加法

  • 上商0:+y\*
  • 上商1:+-y\*

|------------------------|-----------|-------------------------------|
| 被除数(余数) | 商 | 说 明 |
| 0.1011 + 1.0011 | 0.0000 | +-y\*补(减除数) |
| 1.1110 1.1100 + 0.1101 | 0 0 | 余数为负,上商0 ← 1位 +y\*补 (加除数) |
| 0.1001 1.0010 + 1.0011 | 01 01 | 余数为正,上商1 ← 1位 +-y\*补(减除数) |
| 0.0101 0.1010 + 1.0011 | 011 011 | 余数为正,上商1 ← 1位 +-y\*补(减除数) |
| 1.1101 1.1010 + 0.1101 | 0110 0110 | 余数为负,上商0 ← 1位 +y\*补 (加除数) |
| 0.0111 | 01101 | 余数为正,上商1 |

最后答案还是相同的:0.1101

3、补码除法

补码除法常采用加减交替法

算法规则如下:

  1. 符号位参加运算,除数与被除数均用双符号补码表示。
  2. ++被除数与除数同号 ,被除数减去 除数;被除数与除数异号 ,被除数加上除数++。
  3. ++余数与除数同号 ,商上1 ,余数左移一位减去除数; 余数与除数异号 ,商上0,余数左移一位加上除数++。(注意:余数左移加上或减去除数后就得到了新余数。)
  4. 采用校正法包括符号在内,重复n+1次3

注意,使用此运算规则,需要修正商符, 商的末位恒置1

简化可得:

|---------------|----|
| x补与y补 | 商值 |
| 同号 | 1 |
| 异号 | 0 |

关于商符:

在小数定点除法中,被除数的绝对值必须小于除数的绝对值,否则商大于1而溢出。因此:

  • x补与y同号 时,x补-y补所得的余数R0补与y异号,商上"0",恰好与商的符号(正)一致;
  • x补与y异号 时,x补+y补所得的余数R0补与y同号,商上"1",这也与商的符号(负)一致。

可见,商符是在求商值过程中自动形成的

  此外,商的符号还可用来判断商是否溢出。例如:

  • x补与y补同号时,若R0补与y补同号,上商"1",即溢出。
  • x补与y补异号时,若R0补与y补异号,上商"0",即溢出。

  当然,对于小数补码运算,商等于"-1"应该是允许的,但这需要特殊处理,为简化问题,这里不予考虑。

举个例子:

例:已知:x=-0.1001, y=+0.1101 求: x÷y

  解:x补=1.0111,y补=0.1101,-y补=1.0011

|------------------------|------------|-----------------------------------|
| 被除数(余数) | 商 上商 | 说 明 |
| 1.0111+ 0.1101 | 0.0000 | x补与y补异号,+y补 |
| 0.0100 0.1000 + 1.0011 | 1 1 | R补与y补同号,上商1 ← 1位 +-y补 |
| 1.1011 1.0110 + 0.1101 | 10 10 | R补与y补异号,上商0 ← 1位 +y补 |
| 0.0011 0.0110 + 1.0011 | 101 101 | R补与y补同号,上商1 ← 1位 +-y补 |
| 1.1001 1.0010 | 1010 10101 | R补与y补异号,上商0 ← 1位,末位商恒置"1" |

所以x÷y补=1.0101

6.4 浮点四则运算

6.4.1 浮点加减运算

首先我们需要知道浮点数的形式:

x = S * r j

由于浮点数尾数的小数点均固定在第一数值位前,尾数的加减运算规则与定点数完全相同 。但由于其阶码的大小又直接反映尾数有效值的小数点位置,++因此当两浮点数阶码不等时,因两尾数小数点的实际位置不一样++,尾数部分无法直接进行加减运算。因此,浮点数加减运算必须按以下n步进行:

对阶:使两数的阶码位置对齐。

尾数求和:将对阶后的两尾数按定点加减运算规则求和(差)。

规格化:为增加有效数字的位数,提高运算精度,必须将求和(差)后的尾数规格化。

舍入:为提高精度,要考虑尾数右移时丢失的数值位。

判断结果:即判断结果是否溢出。

1、对阶

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

例如,两浮点数**x=0.1101×201y=(-0.1010)×211** ,求x+y

很明显这里y的阶码比较大,所以这里需要转换的是x的阶码,由01变为11,也就是从1变成了3,尾数应该右移两位,所以0.1101变为0.0011。此时x=0.0011×211

2、尾数求和

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

eg:如上例中的两数对阶后得:

  x补=00,11;00.0011

  y补=00,11;11.0110

  则Sx+Sy补=00.0011 +11.0110=11.1001

  即x+y补=00,11;11.1001

3、规格化

由第二章可知,尾数S的规格化形式为

如果采用双符号位的补码,则

  1. 当S>0时,其补码规格化形式为:S补=00.1××...×
  2. 当S<0时,其补码规格化形式为:S补=11.0××...×

对S<0时,有两种情况需特殊处理。

  ①S=-1/2,则S补=11.100...0。对于补码而言,它不满足于上面的规格化表示式。为了便于硬件判断,特规定-1/2是规格化的数(对补码而言)。

  ②S=-1,则S补=11.000...0。因小数补码允许表示-1,故**-1视为规格化的数**。

注:规格化又分左规和右规两种。

(1)左规。当尾数出现00.0××...×或11.1××...×时,需左规。左规时尾数左移一位,阶码减1,直到符合补码规格化表示式为止。

如上例求和结果为:

  x+y补=00,11;11.1001

++尾数的第一数值位与符号位相同,需左规,即将其左移一位,同时阶码减1,++ 得x+y补=00,10;11.0010。

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

4、舍入

在对阶和右规的过程中,可能会将尾数的低位丢失,引起误差,影响了精度,为此可用舍入法来提高尾数的精度。常用的舍入方法有三种。

(1)截去法:将多余的位截去,剩下的位不变。其最大误差接近于数据最低位上的1。

特点:有舍无入,具有误差积累。

(2)"0舍1入"法:"0舍1入"法类似于十进制运算中的"四舍五入"法,即在尾数右移时,被移去的最高数值位为0,则舍去;被移去的最高数值位为1,则在尾数的末位加1。这样做可能使尾数又溢出,此时需再做一次右规。

特点:其最大误差是最低位上的-1/2到接近于1/2之间,正误差可以和负误差抵消。是比较理想的方法,但实现起来比较复杂。

(3)"恒置1"法:尾数右移时,不论丢掉的最高数值位是"1"或"0",都使右移后的尾数末位恒置"1"。这种方法同样有使尾数变大和变小的两种可能。

特点:尽管误差范围扩大了,但正负误差可以相互抵消,从统计角度,平均误差为0。因此最后运算结果的准确性提高了。

5、判断溢出
  • 阶码j补=01,××...×为上溢。
  • 阶码j补=10,××...×为下溢,按机器零处理。

阶符为"01"时,需做溢出处理。

6、完整运算

6.4.2 浮点乘除运算

两个浮点数相乘,++其乘积的阶码应为相乘两数的阶码之和++++其乘积的尾数应为相乘两数的尾数之积++

两个浮点数相除,++商的阶码为被除数的阶码减去除数的阶码++++其尾数为被除数的尾数除以除数的尾数所得的商++

步骤如下:

  1. 阶码运算
  2. 尾数运算
  3. 规格化
  4. 舍入处理
相关推荐
YCOSA202516 小时前
雨晨 Windows 10 企业版 LTSC x64 中度精简 1809 迎双节 17763.9257 特别版
windows
我要见SA姐116 小时前
告别 Copilot?Codex 本地化部署指南
运维·数据库·机器学习·oracle·回归
周洲083016 小时前
STM32 ADC 采集实战|电压采集、分压计算、数据滤波
stm32·单片机·嵌入式硬件
sukalot16 小时前
windows 驱动实例分析系列: HidHide 驱动分析 - drivers 篇(四)
windows·驱动开发
SKH.17 小时前
单片机(2)
单片机
DaTou大头18 小时前
STM32第三篇
单片机·嵌入式·电路基础
搞科研的小刘选手18 小时前
【落地武汉 | EI, Scopus 双检索】第二届智能决策与机器学习国际学术会议 (ICIDML 2026)
机器学习·智能决策·学术会议·会议推荐·武汉
H_oRIZoN_19 小时前
Linux入门DAY40(51 单片机入门:GPIO、中断、定时器、PWM、蜂鸣器完整梳理)
单片机·嵌入式硬件
LCG元19 小时前
STM32F103 复位来源诊断实战:RCC_CSR 标志位判优、BKP 复位计数持久化与六种复位源注入实测
stm32·单片机·嵌入式硬件