我一直在研究浮点格式,IEEE754和x87。以下是一个总结:
Total Bits per field
Precision Bits Sign Exponent Mantissa
Single 32 1 8 23 (+1 implicit)
Double 64 1 11 52 (+1 implicit)
Extended (x87) 80 1 15 64
Quadruple 128 1 15 112 (+1 implicit)
我的问题是,为什么高精度格式有这么多指数位?单精度得到的最大值是10^38,我可以看到在极端情况下(宇宙中的原子数量)你可能需要一个更大的指数。但是双精度高达~10^308,扩展和四重精度有更多的指数位。这似乎比实际硬件加速计算所需要的要大得多。(负指数更荒谬!)
话虽如此,尾数位显然很有价值,我想一定有充分的理由牺牲它们来支持指数。那是什么呢?我认为这可能是为了表示两个相邻值之间的差异而不需要次法线,但即使这样也不需要指数有很大的变化(双精度在1023到-1022的全范围内为-6)。
IEEE-754浮点标准源于英特尔开始创建8087数学协处理器时,加州大学伯克利分校的威廉·卡汉教授作为英特尔顾问所做的工作。IEEE-754浮点格式的设计标准之一是尽可能与现有专有浮点格式的功能兼容性。这本书
John F. Palmer和Stephen P.Morse,“8087入门”。威利,纽约,1984年。
特别提到CDC6600的60位浮点格式,相对于双精度格式,具有11位指数和48位尾数。
以下发表的采访(莫名其妙地将Jerome Coonen的名字篡改为Gerome Kunan)简要概述了IEEE-754的起源,包括对浮点格式选择的讨论:
Charles Severance,“IEEE754:对William Kahan的采访”,IEEE计算机,第31卷,第3期,1998年3月,第114-115页(在线)
在采访中,William Kahan提到采用非常流行的DECVAX小型机的浮点格式,特别是具有8个指数位的单精度的F格式和具有11个指数位的双精度的G格式。
VAX F格式可以追溯到DEC早期的PDP-11架构,选择8个指数位的基本原理在PDP-11/40技术备忘录#16中有所陈述:希望能够表示所有重要的物理常数,包括普朗克常数(6.626070040 x 10-34)和阿伏伽德罗常数(6.022140857 x 1023)。
VAX最初使用D格式来实现双精度,它使用与F格式相同数量的指数位,即8。这被发现在中间计算中通过下限溢位引起麻烦,例如在LAPACK线性代数例程中,正如James Demmel在1992年2月16日星期日NA Digest第92卷:第7期的贡献中所指出的那样。在对Kahan的采访中也提到了这个问题,其中提到随后引入的VAX G格式受到了CDC6600浮点格式的启发。
David Stephenson,“二进制浮点运算的拟议标准”,IEEE计算机,第14卷,第3期,1981年3月),第51-62页(在线)
解释IEEE-754双精度指数位数的选择如下:
对于64位格式,主要考虑的是范围;至少,希望任何两个32位数字的乘积都不会溢出64位格式。指数范围的最终选择规定,八个32位项的乘积不能溢出64位格式——这对优化编译器的用户来说可能是一个福音,优化编译器会根据细心的程序员指定的算术运算序列重新排序。
IEEE-754的“扩展”浮点类型是专门作为中间格式引入的,可以简化相应“常规”浮点类型的准确标准数学函数的实现。
Jerome T. Coonen,“对二进制浮点运算拟议标准的贡献”。加州大学伯克利分校博士论文,1984年
声明前体是IBM709x和Univac 1108机器中的扩展累加器,但我不熟悉用于这些机器的格式。
根据Coonen的说法,扩展格式中尾数位数的选择是由二进制-十进制转换以及一般幂化xy的需要驱动的。Palmer/Morse也提到了幂化并提供了详细信息:由于幂化的误差放大特性,使用扩展格式的朴素计算需要尾数中的额外位数与常规格式的指数中的位数一样多,以提供准确的结果。由于双精度使用11个指数位,因此双扩展格式需要64个尾数位。
除了库宁的博士论文之外,我还检查了IEEE-754标准发布前发表的文件草稿,但无法找到双扩展格式中15个指数位数的陈述理由。
从x87浮点单元的个人设计经验来看,我意识到基本数学函数的直接实现,没有中间溢出的危险,至少需要三个额外的指数位。特别是使用15位可能是硬件设计的产物。8086CPU使用16位字作为基本构建块,因此双扩展格式中64个尾数位的要求将导致包含80位(=五个字)的格式,为指数留下15位。