IEEE 754 浮点数算法模型
更多参见:
基本规定
两种基本的浮点格式:单精度、和双精度
IEEE 单精度格式具有 24 位有效数字精度,并总共占用 32 位。 IEEE 双精度格式具有 53 位有效数字精度,并总共占用 64 位
两种扩展浮点格式:单精度扩展和双精度扩展
此标准并未规定这些格式的精确精度和大小,但它指定了最小精度和大小。例如,IEEE 双精度扩展格式必须至少具有 64 位有效数字精度,并至少总共占用 79 位
浮点运算的精确度要求:加、减、乘、除、平方根、余数、将浮点格式的数舍入为整数值、在不同浮点格式之间转换、在浮点和整数格式之间转换以及比较
求余和比较运算必须精确无误
其他的每种运算必须向其目标提供精确的结果,除非没有此类结果,或者该结果不满足目标格式。对于后一种情况,运算必须按照下面介绍的规定舍入模式的规则对精确结果进行最低限度的修改,并将经过此类修改的结果提供给运算的目标
在十进制字符串和两种基本浮点格式之一的二进制浮点数之间进行转换的准确性、单一性和一致性要求
对于在指定范围内的操作数,这些转换必须生成精确的结果(如果可能的话),或者按照规定舍入模式的规则,对此类精确结果进行最低限度的修改。对于不在指定范围内的操作数,这些转换生成的结果与精确结果之间的差值不得超过取决于舍入模式的指定误差
五种类型的 IEEE 浮点异常,以及用于向用户指示发生这些类型的异常的条件
无效运算
除以零
溢出
下溢
不精确
四种舍入方向
向最接近的可表示的值,当有两个最接近的可表示的值时首选“偶数”值
向负无穷大舍入(向下)
向正无穷大舍入(向上)
向 0 舍入(截断)
舍入精度
如果系统提供双精度扩展格式的结果,则用户可以指定将此类结果舍入到单精度格式或双精度格式的精度
IEEE 格式
存储格式
浮点格式是一种数据结构,用于指定包含浮点数的字段、这些字段的布局及其算术解释。浮点存储格式指定如何将浮点格式存储在内存中。IEEE 标准定义了这些格式,但具体选择哪种存储格式由实现工具决定。
汇编语言软件有时取决于所使用的存储格式,但更高级别的语言通常仅处理浮点数据类型的语言概念。 这些类型在不同的高级语言中具有不同的名称,并且与表中所示的 IEEE 格式相对应。
IEEE 754 明确规定了单精度浮点格式和双精度浮点格式,并为这两种基本格式分别定义了一组扩展格式。下表中 long double
适用于 IEEE 标准定义的一种双精度扩展格式。
IEEE 精度 | C/C++ |
---|---|
单精度 | float |
双精度 | double |
双精度扩展 | long double |
四倍精度 | long double |
单精度格式
IEEE 单精度格式由三个字段组成:
- 23 位小数
f
- 8 位偏置指数
e
- 1 位符号
s
。
这些字段连续存储在一个 32 位字中,如下图所示:
0:22 位包含 23 位小数 f
,其中第 0 位是小数的最低有效位,第 22 位是最高有效位;23:30 位包含 8 位偏置指数 e
,第 23 位是偏置指数的最低有效位,第 30 位是最高有效位;最高的第 31 位包含符号位 s
。
下表显示一侧的三个组成字段 s
、e
和 f
的值与另一侧的单精度格式位模式表示的值之间的对应关系;u 意味着所指示的字段的值与确定特定单精度格式位模式的值无关。
单精度格式位模式 | 值 |
---|---|
0 < e < 255 | $-1^s \times 2^{e-127} \times 1.f$(正规数) |
e = 0; f ≠ 0 | $-1^s \times 2^{-126} \times 0.f$(次正规数) |
e = 0; f = 0 | $-1^s \times 0.0$(有符号的零) |
s = 0; e = 255; f = 0 | +INF(正无穷大) |
s = 1; e = 255; f = 0 | –INF(负无穷大) |
s = u; e = 255; f ≠ 0 | NaN(Not-a-Number,非数值) |
注意,当 e
< 255 时,为单精度格式位模式分配的值是使用以下方法构成的:将二进制基数点插入到紧邻小数最高有效位的左侧,将一个隐含位插入到紧邻二进制点的左侧,因而以二进制位置表示法来表示一个带分数(整数加小数,其中 0 ≤ 小数 < 1)。
如此构成的带分数称为单精度格式有效数字。之所以称为隐含位的原因是,在单精度格式位模式中没有显式指定其值,但偏置指数字段的值隐式指定了该值。
对于单精度格式,正规数和次正规数的差别在于正规数有效数字的前导位(二进制点左侧的位)为 1,而次正规数有效数字的前导位为 0。在 IEEE 标准 754 中,单精度格式次正规数称为单精度格式非规格化数。
在单精度格式正规数中 23 位小数加上隐含前导有效数位共提供了 24 位精度。
附注:e = 1 时,$2^{-126} \times 1.f$ 已经是正规数表示的最小值了,即这个数是形如
1.xxxxxx
这类数的最小表示。那如何表示比这个更小的数呢? 可以看到,我们可以直接用0.000xxx
这种模式进行表示,差别就是前导是 1 还是 0,这就引入了次正规数和前导有效数位隐含位两个概念。上面所说的隐含位,本质上是可以通过 e 是否等于 0 判断的,所以叫隐含。
双精度格式
IEEE 双精度格式由三个字段组成:
- 52 位小数
f
- 11 位偏置指数
e
- 1 位符号
s
。
这些字段连续存储在两个 32 位字中,如下图所示。
在 x86 体系结构中,较低地址的 32 位字包含小数的 32 位最低有效位。
如果用 f[31:0]
表示小数的 32 位最低有效位,则在这 32 位最低有效位中,第 0 位是整个小数的最低有效位,而第 31 位则是最高有效位。在另一个 32 位字中,0:19 位包含 20 位小数的最高有效位 f[51:32]
,其中第 0 位是这 20 位最高有效位中的最低有效位,而第 19 位是整个小数的最高有效位;20:30 位包含 11 位偏置指数 e
,其中第 20 位是偏置指数的最低有效位,而第 30 位是最高有效位;最高的第 31 位包含符号位 s
。
这三个字段中的位模式的值将决定整个位模式所表示的值。
下表显示一侧的三个组成字段中位的值与另一侧双精度格式位模式表示值的对应关系;u 意味着所指示的字段的值与确定特定双精度格式位模式的值无关。
双精度格式位模式 | 值 |
---|---|
0 < e < 2047 | $-1^s \times 2^{e-1023} \times 1.f$(正规数) |
e = 0; f ≠ 0 | $-1^s \times 2^{-1022} \times 0.f$(次正规数) |
e = 0; f = 0 | $-1^s \times 0.0$(有符号的零) |
s = 0; e = 2047; f = 0 | +INF(正无穷大) |
s = 1; e = 2047; f = 0 | –INF(负无穷大) |
s = u; e = 2047; f ≠ 0 | NaN(Not-a-Number,非数值) |
请注意,当 e
< 2047 时,赋予双精度格式位模式的值是使用以下方法构成:将二进制基数点插入到紧邻小数最高有效位的左侧,将一个隐含位插入到紧邻二进制点的左侧。如此构成的数字称为有效数字。之所以称为隐含位的原因是,在双精度格式位模式中没有显式指定其值,但偏置指数字段的值隐式指定了该值。
对于双精度格式,正规数和次正规数的差别在于正规数有效数字的前导位(二进制点左侧的位)为 1,而次正规数有效数字的前导位为 0。 在 IEEE 标准 754 中,双精度格式次正规数称为双精度格式非正规数。
在双精度格式正规数中 52 位小数加上隐含前导有效数位共提供了 53 位精度。