Lisp 交互式 emacs 乘法不正确

Lisp interactive emacs multiplying incorrectly

我运行 Emacs Lisp 交互的以下代码:

(defun square (x) (* x x))
(square (square (square 1001)))

这给了我 1114476179152563777。但是,((1001^2)^2)^2 实际上是 1008028056070056028008001。 这怎么可能?

Emacs Lisp 不实现 bignums,它使用机器的整数类型。它支持的整数范围在most-negative-fixnummost-positive-fixnum之间。在 64 位系统上,most-positive-fixnum 将是 261-1,它有大约 20 个十进制数字。

请参阅 Elisp 手册中的 Integer Basics

你的正确计算结果是25位,比这个大很多。计算溢出并回绕。它应该是正确的模 262.

您可以改用浮点数。它具有更大的范围,尽管非常大的数字会失去精度。

(square (square (square 1001.0)))
1.008028056070056e+24

@Barmar 的回答对于 Emacs 版本 < 27 是准确的。

在 Emacs 27 中添加了 bignum 支持。新闻说:

** Emacs Lisp integers can now be of arbitrary size. Emacs uses the GNU Multiple Precision (GMP) library to support integers whose size is too large to support natively. The integers supported natively are known as "fixnums", while the larger ones are "bignums". The new predicates 'bignump' and 'fixnump' can be used to distinguish between these two types of integers.

All the arithmetic, comparison, and logical (a.k.a. "bitwise") operations where bignums make sense now support both fixnums and bignums. However, note that unlike fixnums, bignums will not compare equal with 'eq', you must use 'eql' instead. (Numerical comparison with '=' works on both, of course.)

Since large bignums consume a lot of memory, Emacs limits the size of the largest bignum a Lisp program is allowed to create. The nonnegative value of the new variable 'integer-width' specifies the maximum number of bits allowed in a bignum. Emacs signals an integer overflow error if this limit is exceeded.

Several primitive functions formerly returned floats or lists of integers to represent integers that did not fit into fixnums. These functions now simply return integers instead. Affected functions include functions like 'encode-char' that compute code-points, functions like 'file-attributes' that compute file sizes and other attributes, functions like 'process-id' that compute process IDs, and functions like 'user-uid' and 'group-gid' that compute user and group IDs.

并且确实使用了我的 27.0.50 版本:

(defun square (x) (* x x))
square

(square (square (square 1001)))
1008028056070056028008001