1、浮点运算步骤
①0操作数的检查,看有无简化操作的可能。
②比较阶码大小并完成对阶(小阶向大阶对齐)。
③尾数进行加或减运算。
(在进行尾数加减前,浮点运算器会自动把原码形式的尾数转换成补码形式。)
④结果规格化并进行舍入处理。
判断有无溢出,有则右规。
再判断是否符合补码一般规格化形式,否则左规。
(尾数右移一位,阶码加一;尾数左移一位,阶码减一。)
规格化总结:
①原码规格化后
正数为0.1××××××××…××的形式
负数为1.1××××××××…××的形式
②补码规格化后
正数为0.1××××××××…××的形式
负数为1.0××××××××…××的形式
舍入处理:就近舍入(0舍1入):类似“四舍五入”。
溢出判断和处理:
①阶码上溢,一般认为是+∞和-∞。
②阶码下溢,则数值为0.
③尾数上溢,两个同符号位的数相加。处理方法是尾数右移,阶码加一。
④尾数下溢。尾数右移时,最低位从最右端流出,要进行舍入处理。
2、例题分析
题目:设x=+2^010×0.11011011, y=-2^100×0.10101100,求x+y.
①0操作数检查(非0)
②对阶:阶码对齐后才能加减。规则是阶码小的向阶码大的数对齐。(标记处为符号数)
若△E=0,表示两数阶码相等Ex=Ey;
若△E>0,表示两数阶码相等Ex>Ey;
若△E<0,表示两数阶码相等Ex<Ey;
当Ex≠Ey时,要通过尾数的移动以改变Ex或Ey,使之相等。
[x]浮=00010,00.11011011; [y]浮=00100,11.01010100;
阶差=[Ex]补-[Ey]补=00010-00100=11110
即阶差为-2,Mx右移两位(尾数右移),Ex加2.
[x]浮=00100,00.00110110(11)
③尾数相加
== 00==.00110110(11)+11.01010100=11.10001010(11)
④结果规格化
若两符号位不等,即溢出时,则右规。
若最高有效位与符号位相同,表明不规格化,需左规。
3、补充例题
(1)若 f1(n)的计算结果为(7F80 0000)16,则其二进制数真值是什么?(5 分)
(2)若 n=24,则 f1(n)的结果用 IEEE 754 表示为什么?(用十六进制数表示)
(3)若将 float 改为 int,则函数 f1(0)是否会出现死循环?理由是什么?
解题:(7F70 0000)16=(0111 1111 0111 0000 0000 0000 0000 0000)2
根据 IEEE 754 标准中 32 位格式的规定可知,符号位 S=0,阶码 E=11111110,尾数M=1110000 0000 0000 0000 0000。 (S、E、M 各 1 分)
因此,二进制真值为:+2^(254-127)×1.111=+1.111×2^127
(2)若 n=24,本质上就是用 IEEE754 标准记录二进制数11 … 1,其中包含 25 个 1。写成规格化形式为:+11 … 1 = +1.11 … 1 × 2
24,因此有 S=0、E=24+127=151 和 M=1 … 1(即
24 个 1)。然而,32 位的 IEEE754 标准中,尾数只有 23 位,无法放下 24 个 1,因此需要采用 0 舍 1 进法进行处理,得到+(2.0)10 × 2
^24 = +(1.1 × 2^25)2。 (1 分)
因此,实际的 S、E、M 字段分别为 S=0、E=25+127=152、M=1000… 0,即结果为:
0 10011000 1000 0000 0000 0000 0000 000
结果用十六进制表示为:(4C40 0000)16
(3)若将函数 f1(n)中的 float 改为 int,则会出现死循环。
理由如下:对于函数 f1(0),有 n=0。由于 n 属于 unsigned int 型,它的类型级别比 int 型高,因此在执行 n-1 后需要将 n-1 的结果-1 值转换为 unsigned int 类型。由于-1 用补码表示为 32 个 1,因此 n-1 的结果是 32 个 1,即 32 位无符号数的最大值。这样判断条件 i<=n-1 将永远成立,从而进入死循环。