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-fixnum
和most-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
我运行 Emacs Lisp 交互的以下代码:
(defun square (x) (* x x))
(square (square (square 1001)))
这给了我 1114476179152563777
。但是,((1001^2)^2)^2
实际上是 1008028056070056028008001
。
这怎么可能?
Emacs Lisp 不实现 bignums,它使用机器的整数类型。它支持的整数范围在most-negative-fixnum
和most-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