前言:说完整数运算,我们来继续说说浮点数运算
浮点数的表示
IEEE 754 标准
32 位机器下,单精度浮点数的表示方法如下:
在机器中这样表示:
- S 是符号位
-
Exponent 是阶码
规格化阶码范围为 0000 0001 (-126) ~ 1111 1110 (127)。
-
Significand 是部分尾数
也就是上图中蓝色的 xxxx 部分。IEEE 754 标准隐藏了最开始的那个 1。也就是说,虽然只有 23 位。但实际上有 24 位
一些特殊的浮点数
- +/-0
- 正负无穷
- 非数
- 非规格化数字
用规格化表示的浮点数有范围,正数最小的值是
- 符号 S:0
- 阶码 E:0000 0001
- 尾数 S:全为 0
得到最小正数:
那么 0~ 就是非规格化的数字。
这一段这样表示(非规格化):
- 尾数:不全 0
- 阶码:全 0
浮点数的运算
三种运算
这三种运算结果可能产生以下几种情况:
阶码上溢:一个正指数超过了最大允许值 => 正负无穷或者溢出
阶码下溢:一个负指数超过了最小允许值 => +0/-0
尾数溢出:最高有效位有进位 => 需要右规
非规格化尾数:数值部分高位为 0 => 需要左规
右规或对阶时:右端有效位丢失 => 尾数舍入
IEEE 754 标准规定的五种异常情况:
- 无效运算(无意义)
- 运算时有一个数字是非有限数
- 结果无效
- 除以 0(即:无穷大)
- 数太大(阶上溢):对于单精度浮点数,指阶码 E > 1111 1110
- 数太小(阶下溢):对于单精度浮点数,指阶码 E < 0000 0001
- 结果不精确(舍入时引起)
上述情况硬件可以捕捉到,因此这些异常可设定让硬件处理,页可设定让软件处理。让硬件处理时,称为硬件陷阱
浮点数加减基本要点
有两点需要注意!
- IEEE 754 规定中间结果必须在右边加 2 个附加位
- IEEE 754 的就近舍入规则
浮点运算单元(FPU)
浮点数运算和整数运算不同,所以运算单元当然不同。早期的浮点处理器是作为 CPU 的「外置协处理器」出现的。x87 FPU 特指与 x86 处理器配套的「浮点协处理器架构」
有以下要点:
-
浮点寄存器采用「栈结构」
深度为 8,宽度为 80 位。即 8 个 80 位的寄存器
名称为 ST(0) ~ ST(7),栈顶为 ST(0),编号分别为 0 ~ 7
- 所有浮点运算都按 80 位拓展精度进行
- 浮点数在浮点寄存器和内存之间传送
- float、double、long double 型的变量在内存中分别用 IEEE 754 单精度、双精度、扩展精度表示,分别占 32 位,64 位,96 位(前 16 位无效)
- float、double、long double 类型变量在浮点寄存器中都用 80 位拓展精度表示
- 从浮点寄存器到内存:80 位拓展精度格式转换为 32 位或者 64 位
- 从内存到浮点寄存器:32 位或者 64 位转换为 80 位扩展精度格式