浮点数
1. 什么是浮点数
在计算机系统的发展过程中,曾经提出过多种方法表达实数。典型的比如相对于浮点数的定点数(Fixed Point Number)。在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。SQL 中的 NUMBER 数据类型就是利用定点数来定义的。还有一种提议的表达方式为有理数表达方式,即用两个整数的比值来表达实数。
定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。最终,绝大多数现代的计算机系统采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa,尾数有时也称为有效数字——Significand;尾数实际上是有效数字的非正式说法),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。比如 123.45 用十进制科学计数法可以表达为 1.2345 × 102 浮点数的基数什么意思,其中 1.2345 为尾数,
10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。
2. IEEE 浮点数
计算机中是用有限的连续字节保存浮点数的。在 IEEE 标准中,浮点数是将特定长度的连续字节的所有二进制位分割为特定宽度的符号域,指数域和尾数域三个域,其中保存的值分别用于表示给定二进制浮点数中的符号,指数和尾数。这样,通过尾数和可以调节的指数(所以称为"浮点")就可以表达给定的数值了。
IEEE 754 指定:
⏹ 两种基本的浮点格式:单精度和双精度。
IEEE 单精度格式具有 24 位有效数字精度,并总共占用 32 位。
IEEE 双精度格式具有 53 位有效数字精度,并总共占用 64 位。
⏹ 两种扩展浮点格式:单精度扩展和双精度扩展。此标准并未规定这些格式的精确精度
和和大小,但它指定了最小精度和大小。例如,IEEE 双精度扩展格式必须至少具有 64 位有效数字精度,并总共占用至少 79 位。
具体的格式参见下面的图例:
3. 浮点格式
浮点格式是一种数据结构,用于指定包含浮点数的字段、这些字段的布局及其算术解释。浮点存储格式指定如何将浮点格式存储在内存中。IEEE 标准定义了这些格式,但具体选择
哪种存储格式由实现工具决定。
汇编语言软件有时取决于所使用的存储格式,但更高级别的语言通常仅处理浮点数据类型的语言概念。这些类型在不同的高级语言中具有不同的名称,并且与表中所示的IEEE 格式相对应。
IEEE 精度 | C、C++ | Fortran (仅限 SPARC) |
单精度 | float | REAL 或 REAL*4 |
双精度 | double | DOUBLE PRECISION 或 REAL*8 |
双精度扩展 | long double | REAL*16 |
IEEE 754 明确规定了单精度浮点格式和双精度浮点格式,并为这两种基本格式分别定义了
一组扩展格式。表中显示的 long double 和 REAL*16 类型适用于 IEEE 标准定义的一种双精度扩展格式。
3.1.单精度格式
IEEE 单精度格式由三个字段组成:23 位小数 f ; 8 位偏置指数 e ;以及 1 位符号 s。这些字段连续存储在一个 32 位字中(如下图所示)。
0:22 位包含 23 位小数 f,其中第 0 位是小数的最低有效位,第 22 位是最高有效位。
IEEE 标准要求浮点数必须是规范的。这意味着尾数的小数点左侧必须为 1,因此我们在保存尾数的时候,可以省略小数点前面这个 1,从而腾出一个二进制位来保存更多的尾数。这样我们实际上用 23 位长的尾数域表达了 24 位的尾数。
23:30 位包含 8 位偏置指数 e,第 23 位是偏置指数的最低有效位,第 30 位是最高有效位。
8 位的指数为可以表达 0 到 255 之间的 256 个指数值。但是,指数可以为正数,也可以为负数。为了处理负指数的情况,实际的指数值按要求需要加上一个偏差(Bias)值作为保存在指数域中的值,单精度数的偏差值为 127;偏差的引入使得对于单精度数,实际可以表达的指数值的范围就变成 -127 到 128 之间(包含两端)。在本文中,最小指数和最大指数分别用 emin 和 emax 来表达。稍后将介绍实际的指数值 -127(保存为全0)以及 +128(保存为全 1)保留用作特殊值的处理。
最高的第 31 位包含符号位s。s为0表示数值为正数,而s为1则表示负数。
3.2.双精度格式
IEEE 双精度格式由三个字段组成:52 位小数 f ; 11 位偏置指数 e ;以及 1 位符号s。这些字段连续存储在两个 32 位字中(如下图所示)。在 SPARC 体系结构中,较高地址的 32 位字包含小数的 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。
上图将这两个连续的 32 位字按一个 64 位字那样进行了编号,其中
0:51 位包含 52 位小数 f,其中第 0 位是小数的最低有效位,第 51 位是最高有效位。
IEEE 标准要求浮点数必须是规范的。这意味着尾数的小数点左侧必须为 1,因此我们在保存尾数的时候,可以省略小数点前面这个 1,从而腾出一个二进制位来保存更多的尾数。这样我们实际上用 52 位长的尾数域表达了 53 位的尾数。
52:62 位包含 11 位偏置指数 e,第 52 位是偏置指数的最低有效位,第 62 位是最高有
效位。
11 位的指数为可以表达 0 到 2047 之间的2048个指数值。但是,指数可以为正数,也可以为负数。为了处理负指数的情况,实际的指数值按要求需要加上一个偏差(Bias)值作为保存在指数域中的值,单精度数的偏差值为1023;偏差的引入使得对于单精度数,实际可以表达的指数值的范围就变成 -1023到1024之间(包含两端)。在本文中,最小指数和最大指数分别用 emin 和 emax 来表达。稍后将介绍实际的指数值 -1023(保存为全0)以及 +1024(保存为全 1)保留用作特殊值的处理。
最高的第 63 位包含符号位s。s为0表示数值为正数,而s为1则表示负数。
3.3.双精度扩展格式 (SPARC)
SPARC 浮点环境的四倍精度格式符合双精度扩展格式的 IEEE 定义。四倍精度格式占用 32 位字并包含以下三个字段:112 位小数 f、15 位偏置指数 e 和 1 位符号 s。这三个字段连续存储,如图2-3 所示。
地址最高的 32 位字包含小数的 32 位最低有效位,用 f[31:0] 表示。紧邻的两个 32 位字分
别包含 f[63:32] 和 f[95:64]。下面的 0:15 位包含小数的 16 位最高有效位 f[111:96],其中第 0 位是这 16 位的最低有效位,而第 15 位是整个小数的最高有效位。16:30 位包含 15 位偏置指数 e,其中第 16 位是该偏置指数的最低有效位,而第 30 位是最高有效位;第 31 位包含符号位 s。
下图将这四个连续的 32 位字按一个 128 位字那样进行了编号,其中 0:111 位存储小数 f ; 112:126 位存储 15 位偏置指数 e ;而第 127 位存储符号位 s。
3.4.双精度扩展格式 (x86)
该浮点环境双精度扩展格式符合双精度扩展格式的 IEEE 定义。它包含四个字段:63 位小数 f、1 位显式前导有效数位 j、15 位偏置指数 e 以及 1 位符号 s。
在 x86 体系结构系列中,这些字段连续存储在十个相连地址的 8 位字节中。由于 UNIXSystem V Application Binary Interface Intel 386 Processor Supplement (Intel ABI) 要求双精度扩展参数,从而占用堆栈中三个相连地址的 32 位字,其中地址最高字的 16 位最高有效位未用,如下图所示。
地址最低的 32 位字包含小数的 32 位最低有效位 f[31:0],其中第 0 位是整个小数的最低有效位,而第 31 位则是 32 位最低有效位的最高有效位。地址居中的 32 位字中,0:30 位包含小数的 31 位最高有效位 f[62:32] (其中第 0 位是这 31 位最高有效位的最低有效位,而第 30 位是整个小数的最高有效位);地址居中 32 位字的第 31 位包含显式前导有效数位 j。
地址最高的 32 位字中,0:14 位包含 15 位偏置指数 e,其中第 0 位是该偏置指数的最低有
效位,而第 14 位是最高有效位;第 15 位包含符号位 s。虽然地址最高的 32 位字的最高 16 位未被 x86 体系结构系列使用,但如上所述,它们对于符合 Intel ABI 规定是至关重要的。
4. 将实数转换成浮点数
4.1 浮点数的规范化
同样的数值可以有多种浮点数表达方式,比如上面例子中的 123.45 可以表达为 12.345 × 101,0.12345 × 103 或者 1.2345 × 102。因为这种多样性,有必要对其加以规范化以达到统一表达的目标。规范的(Normalized)浮点数表达方式具有如下形式:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论