3.2 浮点数基础

浮点数适用于表示非整数数值。其取值范围与你所用机器上 C 语言的 double 数据类型一致。在几乎所有 Emacs 支持的计算机上,浮点数均采用 IEEE binary64(双精度)浮点格式—— 该格式由 IEEE Std 754-2019 标准化,David Goldberg 的论文 “What Every Computer Scientist Should Know About Floating-Point Arithmetic” 也对其有深入探讨。现代平台上的浮点运算基本遵循 IEEE-754 标准,但部分系统(尤其是 32 位 x86 架构)的运算结果可能无法保证正确舍入。

在某些老旧计算机系统上,Emacs 可能不使用 IEEE 浮点数。我们已知有一个这样的系统:运行 NetBSD 并使用 GCC 10.4.0 的 VAX 计算机,Emacs 可以正常运行,但不遵循 IEEE-754,而是改用 VAX 的 ‘D_Floating’ 格式。基于 IBM System/370 的大型机及其 XL/C 编译器也支持十六进制浮点数格式,但 Emacs 尚未在这类配置下编译构建过。

浮点数的读取语法要求必须包含小数点、指数,或两者同时具备。数值及其指数前可添加可选符号(‘+’ 或 ‘-’)。例如,‘1500.0’、‘+15e2’、‘15.0e+2’、‘+1500000e-3’ 和 ‘.15e4’ 是表示数值 1500 的五种浮点数写法,它们完全等价。与 Common Lisp 一致,Emacs Lisp 规定:对于不含指数的浮点数,小数点后必须至少有一位数字;因此 ‘1500.’ 会被解析为整数,而非浮点数。

= 等数值比较操作中,Emacs Lisp 将 -0.0 视为与普通零在数值上相等。这一行为遵循 IEEE 浮点标准 —— 该标准规定,即便其他操作可区分 -0.00.0,二者在数值层面仍相等。

IEEE 浮点标准支持将正无穷和负无穷作为浮点值,还定义了一类名为 NaN (即 “not a number非数值”)的值;当数值函数无合法计算结果时,会返回此类值。例如,(/ 0.0 0.0) 会返回 NaN。NaN 在数值上永不等于任何值,甚至不等于其自身。NaN 包含符号和尾数,若两个 NaN 的符号与尾数均一致,非数值函数会将它们判定为相等。NaN 的尾数及其字符串表示形式均依赖于具体机器。

当涉及 NaN 和带符号零(0.0 或 −0.0)时,eqlequalsxhash-eqlsxhash-equalgethash 这类非数值函数判断的是值是否不可区分,而非数值上是否相等。例如:当 xy 是同一个 NaN 时,(equal x y) 返回 t,而 (= x y) 进行数值比较,返回 nil;反之,(equal 0.0 -0.0) 返回 nil,而 (= 0.0 -0.0) 返回 t

以下是这些特殊浮点值的读取语法:

infinity

无穷大:‘1.0e+INF’ 和 ‘-1.0e+INF

not-a-number

非数值(NaN):‘0.0e+NaN’ 和 ‘-0.0e+NaN

在不支持 IEEE 浮点运算的老旧系统中,无穷大和 NaN 不可用。例如在 1980 年左右的 VAX 机器上,Lisp 会将 ‘1.0e+INF’ 解析为一个很大但有限的浮点数,将 ‘0.0e+NaN’ 解析为其他非数值型 Lisp 对象,若将其用于数值运算会触发错误。

以下是专门用于处理浮点数的函数:

Function: isnan x

该谓词函数的返回值规则:若浮点类型参数 x 是 NaN,返回 t;否则返回 nil

Function: frexp x

该函数返回一个 cons 单元格 (s . e),其中 se 分别是浮点数 x 的尾数(significand)和指数(exponent)。

x 是有限值:s 是介于 0.5(包含)和 1.0(不包含)之间的浮点数,e 是整数,且满足 x = s * 2**e。 若 x 是 0 或无穷大:s 与 x 相等。 若 x 是 NaN:s 也为 NaN。 若 x 是 0,e 为 0。

Function: ldexp s e

给定数值型尾数 s 和整数型指数 e,该函数返回浮点数结果为 s * 2**e

Function: copysign x1 x2

该函数将 x2 的符号复制到 x1 的数值上,并返回结果。x1x2 必须均为浮点类型。

Function: logb x

该函数返回 x 的二进制指数。更精确地说: 若 x 是有限非零值,返回值为 \(|x|\) 以 2 为底的对数,向下取整为整数; 若 x 是 0 或无穷大,返回值为无穷大; 若 x 是 NaN,返回值为 NaN。

(logb 10)
     ⇒ 3
(logb 10.0e20)
     ⇒ 69
(logb 0)
     ⇒ -1.0e+INF

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike

JavaScript license information