(二)浮点数
1. 浮点数
1.1. 浮点数格式

浮点数 N:
; :尾数,为一个带符号定点小数; :基数,取 2 的次方,如 2,4,8,16 等**(一般取 2)**; :阶码,为一个带符号定点整数;
尾数决定浮点数精度,即能表示小数点后的位数;
阶码:决定浮点数能表示的范围;
实例分析:浮点数长 16 位,
,阶码 5 位含符号位 1 位,尾数 11 位含符号位 1 位,都用原码形式,写出 的浮点形式; 1)写成科学计数法:
; 2)分析尾数取值:规格化
负数,符号位为 1;
因为
, 需要将小数点左移 9 位,而原数规格化只能移 6 位,所以还有 3 位要放到阶码上; - 规格化:指尾数数据位的最高位必须是有效值(原码为 1,补码和反码为 0);
所以尾数取值为
,注意右侧补 0;
3)分析阶码取值:由于还剩 3 位没移,因此阶码
,负数符号位为 1,原码表示为 ; 因此,浮点数表示为(先阶码后尾数):
;
可以看出,要点在于确定尾数取值,尾数规格化自带移位,剩下的移位用阶码完成;
规格化尾数的浮点数精度是最高的;
1.2. 浮点数的范围

由
,先算出 和 的范围,再计算即可; 注意
考虑规格化与否,会导致尾数表示范围不同;
- 规格化要求尾数最高位必须为 1;
和 采用不同码表示时,范围不同,对应 的范围也会不同; 始终为正, 正负由 决定;
下溢:0 和最大负数,0 和最大正数之间的数无法用浮点数表示(注意 0 可以);
处在下溢区间的数被当作机器 0,不会报错;
与之对比,上溢会产生 overflow 错误;
1.3. 补码规格化
左规:补码运算结果未溢出,但不是规格化,需要将尾数数据位左移,直到满足规格化;
- 尾数左移 1 次,阶码需要减 1;
右规:补码运算结果溢出,将尾数数据位右移 1 次;
采用两位符号位时,符号位低位移到数据位最高位,符号位补成相同两位;
阶码对应地加 1;
实例分析:采用两位符号位,00 表示正,11 表示负;
左规:
或 ,需要数据位左移直到最高位为有效位; 右规:
或 ,数据位右移 1 位; - 右移后,
, ;
- 右移后,
1.4. 机器 0
尾数
时,无论阶码 为何值,都按机器 0 处理; 阶码
,即 小于等于其能表示的最小值时,无论尾数 为何值,都按机器 0 处理;
⭐2. IEEE 754 标准
2.1. 格式

短实数:总 32 位,符号位 1 位,阶码 8 位,尾数 23 位;
长实数:总 64 位,符号位 1 位,阶码 11 位,尾数 52 位;
临时实数:总 80 位,符号位 1 位,阶码 15 位,尾数 64 位;
2.2. 表示方式
尾数:原码规格化形式,最高位固定为有效值 1;
- 最高位固定为 1,所以通常省略不写,因此,
位尾数可表示 位定点小数;
- 最高位固定为 1,所以通常省略不写,因此,
阶码:偏移形式,即阶码真值加上一个偏移
; 短实数:偏移
; 长实数:偏移
; 临时实数:偏移
;
实例分析
- 将十进制数 178.125 表示为 IEEE 754 标准浮点数(32 位短实数);
1)表示为二进制真值,即
; 2)小数点移到最左边,表示为
,即 ; 3)阶码
; 4)尾数首位 1 省略,后面要补零,凑到 23 位
; 5)组装:
; 6)一般是写为 16 进制,
;
- IEEE 754 标准浮点数
,求其十进制值;
1)写为二进制:
; 2)符号位
,阶码 ,尾数**(还原最高位 1)** ; 3)阶码真值
,尾数 ,所以真值为 ;
- IEEE 754 标准浮点数
注意事项:1)最高一位是符号位,2)尾数最高位 1,转为二进制要省略,转回十进制要还原;
2.3. 范围(以 32 位短实数为例)
阶码特殊值
阶码全 1:表示无穷大;
阶码全 0:表示机器 0;
尾数范围(不考虑符号):
, ,注意后面是 23 个 1; 阶码范围:
, ; 绝对值范围:
, ; 表示范围:正负数的表示范围是对称的,即
;
3. 浮点数加减法
3.1. 对阶
含义:两个浮点数
和 加减时,需要将阶码变换到相等,才能运算; 方法:小阶向大阶对齐,小阶的尾数右移;
不能大阶对小阶的原因:大阶变小会使得尾数左移,可能超过 1,造成溢出;
计算阶差
,然后小阶码变为大阶码,小阶码的尾数向右移动 位; 尾数为原码,则符号位不参与移位,高位补 0;
尾数为补码,符号位一起移位,高位补符号位;
3.2. 规格化
对阶完成的浮点数
和 ,可以直接对尾数进行加减运算; 然后需要对尾数进行规格化操作;
可能发生左规和右规的情况;
3.3. 舍入
在对阶和右规操作中,尾数的低位可能被移掉;
0 舍 1 入法:若移掉的是 0 则直接舍弃,若是 1 则要进位;
去尾法:直接舍弃;
3.4. 判断溢出
浮点数判断溢出较为复杂:
根据定义:超过浮点数能表示的范围,才叫溢出;
尾数溢出,浮点数不一定溢出;
阶码溢出:浮点数一定溢出;
注意机器 0 的情况;
运算结束后,对阶码进行判断:上溢 or 下溢;
阶码上溢:需要置位溢出表示;
阶码下溢:结果置为机器 0;
实例分析:令
, 。浮点数阶码 6 位,尾数 10 位,均为补码形式,符号位 1 位。求 ; 1)写出二者尾数补码形式
, ; 2)
, ,所以 需要变换,阶码变为 4,尾数右移 2 位; 3)注意到
倒数第二位为 1,右移时需要舍入进位,即最低位 + 1。右移两位后, ; 4)对阶完成,二者尾数相加:
,阶码为 ;
习题
- 16 位浮点数,阶符 1 位,阶码 6 位,数符 1 位,尾数 8 位,当采用补码表示时,所能表示的数的范围是()
A.
B.
C.
D.
答案:B
解析:阶码 7 位带符号定点整数,尾数 9 位带符号定点小数,
; 最大值:
和 同时取最大正数, , ,所以 ; 最小值:
取最小负数, 最大正数, ,所以 ;
- 机器字长 32 位,浮点数阶码 8 位,尾数 24 位,各含 1 位符号。求:最小的规格化正数是多少?
答案:
; 解析:
阶码最小
; 尾数规格化要求最高位为 1,令其余都为 0,则
; 所以
;
- 两个 32 位 IEEE 754 浮点数,
, ,则
A.
且同号; B.
且异号; C.
且同号; D.
且异号; 答案:A
解析
快速比较浮点数大小:尾数决定精度,阶码决定范围(大小)
因为
和 二进制首位都是 1,所以都是负数,同号; 观察到
二进制的第二位为 1,而 二进制第二位为 0,则阶码必有 ; - 且差距极大(至少差
),可以忽略尾数的作用;
- 且差距极大(至少差
则绝对值有
,由于是负数,所以 ;
- 两个 32 位 IEEE 754 浮点数,
- 浮点数阶码和尾数均补码形式,阶码 5 位,尾数 7 位,均含两位符号位。令
, ,则 为
A.
; B.
; C.
; D. 溢出;
答案:D
解析:
, , , ; 先对阶,
, ; 然后相加,
,发生溢出,需要右规; ,对应阶码需要加 1,即 ,阶码发生溢出,故结果溢出;
- 浮点数阶码和尾数均补码形式,阶码 5 位,尾数 7 位,均含两位符号位。令
- 下列叙述中,正确的有()
(1). 对阶操作不会引起阶码上溢或下溢,(2). 右规和尾数舍入都可能引|起阶码上溢,(3). 左规时可能引起阶码下溢,(4). 尾数溢出时结果不一定溢出;
A. (2), (3);
B. (1), (2), (4);
C. (1), (3), (4);
D. 全部;
答案:D
解析
(1):对阶是把小阶变大阶,不会溢出,对;
(2):右规,阶码需要 + 1,可能溢出。舍入,尾数低位 +1,可能导致尾数溢出,进而右规,进而导致阶码溢出,对;
(3):左规:阶码需要 -1,可能会下溢,对;
(4):正确;
- 有下列 C 语言写成的函数
f1,其中unsigned和int类型都是 32 位,float是 IEEE 754 单精度标准;
cint f1(unsigned n) { int sum = 1, power = 1; for (unsigned i = 0; i <= n - 1; ++i) { power *= 2; sum += power; } return sum; }6.1.
n=0时,会出现死循环,为什么?若将变量i和n都改为int,是否还会死循环?为什么?6.2. 将
f1中的int都改为float得到f2,f1(23)和f2(23)的返回值是否相等?机器数(16 进制)各是多少?6.3.
f1(24)=33 554 431,f2(24)=33 554 432.0,二者为什么不相等?6.4.
f1(31)=-1,而不是2^32-1,为什么?若要使得返回值与期望的值相等,n最大为多少?6.5.
f2(127)=0x7F80 0000,对应的值是什么?若要使f2(n)不溢出,最大的n是多少?若要f2(n)结果精确无舍入,n最大多少?解析
6.1
时,因为 无符号,所以有 ,故 恒成立,会出现死循环; 但 有符号时, 为负数, 不成立,不会进入循环,所以不会死循环;
6.2
由代码知,
,故 ; 整数形式下,
; IEEE 754 形式下,小数点移到第一个 1 后面,为
; 则
, ; 则
;
6.3. 原因是尾数右规产生了舍入误差
,没有超出 int 范围,故 int 能正常表示; 对于 IEEE 754,小数点移到第一个 1 后,为
; 此时,省略高位的 1 也要 24 位才能表示尾数,故溢出,需要舍入,由 0 舍 1 入知最低为 +1;
舍入进位后,尾数为
,需要右规,阶码对应 + 1,变为 25; 最后,
的尾数全 0,阶码真值为 25,因此 ,产生了舍入误差;
6.4
超出了 int 表示范围。若表示为 u32则为全 1,全 1 在有符号 int 补码下为 -1;最大为 30,此时 ,恰为 i32最大正数;
6.5.
法一:展开
,发现阶码部分为全 1,故发生上溢,为无穷大; 法二:32 位 IEEE 754 浮点数表示的最大正数是
,而 ,故上溢; 因为
,故 最大值可取 126; 由 6.3 知,尾数位数不能超过 23,即结果的位数不能超过 24,即
,因此 最大值为 23;
结论
若用定点数和浮点数的计算结果相差 1,一般是尾数舍入误差;
若二者误差很大,一般是溢出;
- 有下列 C 语言写成的函数
粗体代码:
boldcode