# J.12 历史回顾与参考文献
<!-- source: p1286 -->

最早的计算机使用定点而非浮点。Burks、Goldstine 与 von Neumann [1946] 在《电子计算装置逻辑设计的初步讨论》中写道：

> “浮动”小数点系统似乎有两个主要目的，两者都源于一个事实：每台机器每字的数字位数，是由设计考虑确定的常数。第一个目的，是在和或积中尽可能保留更多有效数字；第二个目的，是减轻人工估算并在问题中插入“比例因子”的负担。

<!-- source: p1287 -->

> 比例因子是乘法常数，用来让数值保持在机器可表示范围内。
>
> 当然，引入适当比例因子的安排会耗费人的时间，这是无法否认的。我们只是认为，与为机器准备一个有意义的问题所耗的总时间相比，这部分时间所占比例很小。我们觉得浮点的第一个好处多少有些虚幻：为了支持浮点，必须牺牲本可用来让每字保存更多数字的存储容量。因此，浮动二进制小数点的有限好处，能否抵偿存储容量损失，以及算术和控制电路复杂性的增加，在我们看来并不明确。

这让我们看到了早期设计者的立场：节省计算机时间和存储，比节省程序员时间更重要。

最早介绍 Wallace 树、Booth 重编码、SRT 除法、重叠三位组等技术的论文，收录于 Swartzlander [1990]。Anderson 等 [1967] 很好地介绍了早期 IBM 360/91，它使用流水化 Wallace 树、Booth 重编码和迭代除法。Freiman [1961] 分析逐位 SRT 的平均时间，是少数未收入该论文集、却很有价值的历史论文之一。

Mead 与 Conway [1980] 的经典教材认为 CLA 在 VLSI 中成本效益不佳，不鼓励采用。Brent 与 Kung [1982] 的重要论文帮助改变了这一看法。详细 CLA 版图见 Ngai 与 Irwin [1985] 或 Weste 与 Eshraghian [1993]，更理论化的分析见 Leighton [1992]。Takagi、Yasuura 与 Yajima [1985] 详细介绍了带符号数字树乘法器。

IEEE 算术占主导之前，浮点格式很多，重要者包括 IBM 370、DEC VAX 和 Cray。VAX 最接近 IEEE：单精度 F 格式也有隐含位、8 位指数、23 位小数部分，但没有 sticky 位，中点总向上舍入而不是取偶。指数范围略有不同：\(E_{\min}=-128\)，IEEE 为 −126；\(E_{\max}=126\)，IEEE 为 127。主要区别是缺少特殊值与渐进下溢。VAX 的保留操作数类似 signaling NaN，引用它就触发陷阱。最初双精度 D 格式也只有 8 位指数，对许多应用太少，所以后来增加 G 格式，与 IEEE 双精度一样有 11 位指数。VAX 还有 128 位 H 格式。

<!-- source: p1288 -->

IBM 370 使用十六进制而非二进制，因此不能使用隐含首位。单精度含 7 位指数与 24 位小数，即 6 个十六进制数字。原书据此写出最大可表示数为

$$
16^{2^7}=2^{4\times2^7}=2^{2^9},
$$

并与 IEEE 的 \(2^{2^8}\) 比较。十六进制规格化只要求首个十六进制数字非零，换成二进制后，最高三位仍可能为零，因此有效精度可能少于 24 位。采用较高基数，是为了减少浮点加法时的移位量；但在运算时间通常不依赖操作数的机器中，这一优势已不那么重要。

> 译注：上述“最大可表示数”公式为原页原式，只由指数域位数作了数量级比较，未计实际指数偏置、端点和有效数，不能当作两种格式的精确最大有限值；本附录图 J.7 给出的 IEEE 单精度最大无偏置指数为 127。

370 也没有舍入位与 sticky 位，效果上是截断而非舍入，许多计算结果会系统性偏小。它与 VAX、IEEE 还有一点不同：所有位模式都是合法数值。因此，库函数必须另行约定出错时返回什么。例如 IBM FORTRAN 库对 \(\sqrt{-4}\) 竟返回 2！

Cray 算术很有意思，因为它一切以最高浮点性能为目标。指数域 15 位，小数域 48 位。加法没有保护位，乘法比加法更不准确。若把乘法看成 p 个、每个 2p 位的数相加，Cray 会丢弃每个加数的低位，因此不容易分析准确误差。倒数用迭代计算，a/b 则以 a 乘 1/b；两种误差叠加，使除法的最后三位不可靠。至少，Cray 迫使数值分析人员始终保持警觉！

IEEE 标准化始于 1977 年，主要由 W. Kahan 推动，部分基础来自他在多伦多大学 IBM 7094 上的工作 [Kahan 1968]。过程漫长，渐进下溢争议最大。Cleve Moler 曾说，有人建议赴美游客千万别错过三个景点：拉斯维加斯、大峡谷，以及 IEEE 标准委员会会议。标准终于在 1985 年获批。

Intel 8087 是第一个重要商业 IEEE 实现，1981 年就已问世，早于标准定稿，因此保留了最终标准删除的特性，例如 projective bits。据 Kahan 说，扩展双精度的长度取决于 8087 能实现什么。IEEE 并非直接基于某个既有系统，但多数特性在其他系统出现过：CDC 6600 为 INDEFINITE、INFINITY 保留特殊位模式，非规格化数思想见 Goldberg [1967] 与 Kahan [1968]。Kahan 因其浮点贡献获得 1989 年图灵奖。

浮点很少成为大众媒体焦点，但 1994 年 11 月，报纸却充满了浮点除法的报道。

<!-- source: p1289 -->

Intel 当时所有 Pentium 芯片的除法算法出现缺陷。发现者是 Virginia 州 Lynchburg College 的数学教授 Thomas Nicely，他在计算素数倒数时遇到了问题。消息首先刊登在 11 月 7 日的 *Electronic Engineering Times* 头版。

Intel 起初拒不正视，声称只影响理论数学家，并对媒体说：“这甚至算不上勘误……即使你是工程师，也不会遇到它。”压力增大后，Intel 于 11 月 30 日发布白皮书，解释为何认为缺陷不严重。理由之一是：随机选两个浮点数相除，商出错的概率约九十亿分之一。但 Intel 没有解释，为何认为普通客户会随机使用浮点数。

压力持续上升。一个尤其令人不满的事实是，Intel 在 Nicely 之前已知道问题，却决定不公开。最终，12 月 20 日，Intel 宣布无条件更换使用错误算法的 Pentium，并计提一笔当时未公布金额的费用，后来确定为 3 亿美元。

Pentium 采用 J.9 节介绍的简单 SRT 变体。错误出在把商选择表转换为 PLA 时：Intel 显然认为，几个商数字为 2 的表项永远不会被访问，于是据此优化，让这些位置输出 0。然而它们实际会被访问，导致错误。虽然 2048 项中只有 5 项错误，随机输入的错误商概率仍为九十亿分之一。习题 J.34 会进一步研究。

本附录完整书目见后面的“参考文献”页。
