2.5 浮点数的表示与运算

浮点数的格式、规格化与表示范围,IEEE 754 单精度与双精度标准,浮点加减运算的五个步骤,以及 C 语言中的类型转换。

考查要求 ★★★ 重点掌握 浮点数规格化IEEE 754偏置值特殊值浮点加减五步类型转换精度

浮点数的表示

定点数可表示的数字范围有限,但我们不能无限制地增加数据的长度。浮点数把数的范围和精度分别表示:

N=(−1)S×M×REN = (-1)^S \times M \times R^E

其中 SS 为符号,MM 为尾数(定点小数,决定精度),EE 为阶码(定点整数,决定范围),RR 为基数(通常为 2)。

  • 阶码的位数反映了浮点数的表示范围,阶码的值反映小数点的实际位置;
  • 尾数的位数反映了浮点数的精度。

规格化

为了提高运算的精度,需要充分地利用尾数的有效数位,通常采取浮点数规格化的形式:规定尾数的最高数位必须是一个有效值。

  • 左规:当运算结果的尾数的有效位最高位不为有效值时,需要进行左规——尾数每左移一位,阶码减 1。左规可能要进行多次;
  • 右规:当运算结果的尾数的有效位进到小数点前面时(即尾数溢出),需要进行右规——尾数右移一位,阶码加 1。右规只需进行一次。

对基数为 2 的尾数:原码规格化后,正数为 0.1×⋯×0.1\times\cdots\times,负数为 1.1×⋯×1.1\times\cdots\times;补码规格化后,正数为 0.1×⋯×0.1\times\cdots\times,负数为 1.0×⋯×1.0\times\cdots\times(即符号位与最高数值位不同)。

IEEE 754 标准

数符 s1 位阶码 E(移码)8 位尾数 M(原码,隐含最高位 1)23 位单精度 float(32 位):(−1)^s × 1.M × 2^(E − 127)双精度 double(64 位):1 + 11 + 52 位,偏置值 1023
类型数符阶码尾数总位数偏置值
单精度 float182332127(7FH)
双精度 double11152641023(3FFH)

IEEE 754 标准中,阶码用移码(偏置值为 2n−1−12^{n-1} - 1,而不是一般移码的 2n−12^{n-1})表示,尾数用原码表示。规格化尾数的最高位总是 1,所以这一位不存储,而是隐含,因此尾数实际上有 24 位(单精度)。

交互演示IEEE 754 浮点数(输入十进制数,或点击各位)
10111111010000000000000000000000S阶码 E(8 位)尾数 M(23 位,隐含 1.)
十六进制BF400000H符号 S1(负)阶码 E126,真值 e = E − 127 = -1类别规格化数计算(−1)^1 × 1.1 × 2^(126−127) = (−1)^1 × 1.5 × 2^-1实际存储的值-0.75
试试 0.1:它的尾数是无限循环的,只能舍入后存储,所以实际值 ≠ 0.1。这就是 C 语言中 0.1 + 0.2 != 0.3 的原因。

十进制 → IEEE 754 的步骤(以 −0.75 为例):

  1. 转为二进制:−0.75=−0.112=−1.12×2−1-0.75 = -0.11_2 = -1.1_2 \times 2^{-1};
  2. 符号 S=1S = 1;阶码 E=−1+127=126=0111 11102E = -1 + 127 = 126 = 0111\,1110_2;尾数 M=100⋯0M = 100\cdots0(去掉隐含的 1);
  3. 拼接:1 01111110 1000⋯01\ 01111110\ 1000\cdots0,即 BF40 0000H。

浮点数的加减运算

浮点数加减运算的过程比定点运算复杂,需要以下 5 个步骤:

  1. 对阶:使两个操作数的小数点位置对齐,即使两个数的阶码相等。小阶向大阶看齐:阶码小的尾数右移,每右移一位阶码加 1(这样丢失的是低位,影响较小);
  2. 尾数求和:将对阶后的尾数按定点数加(减)运算规则运算;
  3. 规格化:尾数溢出则右规,非规格化则左规;
  4. 舍入:在对阶和右规过程中,可能会将尾数的低位丢失,引起误差。常见的舍入方法有”0 舍 1 入”法和”恒置 1”法(IEEE 754 中默认为”就近舍入到偶数”);
  5. 溢出判断:浮点数的溢出是由阶码决定的。若阶码超出最大值,则上溢(需要中断处理);若阶码小于最小值,则下溢,通常按机器零处理。
动画演示浮点数的加减运算
1. 对阶2. 尾数求和3. 规格化4. 舍入5. 溢出判断阶码尾数X00,00100.11012^1 × 0.8125Y00,01111.01102^3 × -0.625
步骤
1浮点数加减运算的步骤:
2① 对阶:小阶向大阶看齐,
3 小阶的尾数右移 ΔE 位
4② 尾数求和(减法:加上 −Y 的尾数)
5③ 规格化:
6 尾数双符号位 01/10 → 右规 1 位
7 符号位 = 最高数值位 → 左规
8④ 舍入:0 舍 1 入 / 恒置 1
9⑤ 溢出判断:
10 阶码 01 → 上溢;10 → 下溢(机器零)
1/6阶码、尾数均用双符号位补码表示(阶码 3 位数值、尾数 4 位数值)。

C 语言中的浮点数类型转换

转换结果
int → float不会溢出,但 int 有 31 位数值位而 float 尾数只有 24 位,可能有舍入(如 16777217)
int / float → doubledouble 的尾数有 53 位,可以精确表示所有 int 和 float
double → float可能溢出,也可能有舍入
float / double → int小数部分向 0 截断;可能溢出

即时练习

即时练习4 题
点击选项即可作答
  1. 1
    float 型数据通常用 IEEE 754 单精度浮点数格式表示。若编译器将 float 型变量 x 分配在一个 32 位浮点寄存器 FR1 中,且 x = −8.25,则 FR1 的内容是( )。
  2. 2
    下列关于 IEEE 754 单精度浮点数的说法中,错误的是( )。
  3. 3
    浮点数加减运算过程一般包括对阶、尾数运算、规格化、舍入和判溢出等步骤。设浮点数的阶码和尾数均采用补码表示,且位数分别为 5 位和 7 位(均含 2 位符号位)。若有两个数 X = 2⁷ × 29/32,Y = 2⁵ × 5/8,则用浮点加法计算 X + Y 的最终结果是( )。
  4. 4
    假定变量 i、f、d 的数据类型分别为 int、float 和 double(int 用补码表示,float 和 double 分别用 IEEE 754 单精度和双精度格式表示),已知 i = 785,f = 1.5678e3,d = 1.5e100。若在 32 位机器中执行下列关系表达式,则结果为"真"的是( )。
    Ⅰ. i == (int)(float)i Ⅱ. f == (float)(int)f Ⅲ. f == (float)(double)f Ⅳ. (d + f) − d == f
学完了吗?

标记完成后,侧栏会显示进度。进度仅保存在本浏览器中。