我正在Emacs Lisp交互上运行以下代码:
(defun square (x) (* x x))
(square (square (square 1001)))
这给了我1114476179152563777
。但是,((1001^2)^2)^2
实际上是1008028056070056028008001
。
这怎么可能?
答案 0 :(得分:9)
Emacs Lisp没有实现bignums,它使用了机器的整数类型。它支持的整数范围在most-negative-fixnum
和most-positive-fixnum
之间。在64位系统上,most-positive-fixnum
将是2 61 -1,大约有20个十进制数字。
请参见Elisp手册中的Integer Basics。
您的计算正确结果是25位数字,比这大得多。计算溢出并回绕。应该是正确的2 62 模。
您可以改用浮点数。它的范围更大,尽管很多数字会降低精度。
(square (square (square 1001.0)))
1.008028056070056e+24
答案 1 :(得分:9)
@Barmar的答案对于<27的Emacs版本是正确的。
在Emacs中增加了27个bignum支持。新闻说:
** Emacs Lisp整数现在可以具有任意大小。 Emacs使用GNU Multiple Precision(GMP)库来支持 整数,其大小太大而无法本地支持。整数 本机支持的称为“ fixnums”,而较大的 “ bignums”。新的谓词“ bignump”和“ fixnump”可用于 区分这两种类型的整数。
所有算术,比较和逻辑(也称为“按位”) bignum有意义的操作现在支持fixnum和 bignums。但是,请注意,与fixnums不同,bignums不会进行比较 等于“ eq”,则必须改用“ eql”。 (数值比较 当然,两者都可以使用'='。
由于大型bignum占用大量内存,因此Emacs限制了 Lisp程序可以创建的最大bignum。的 新变量'integer-width'的非负值指定 bignum中允许的最大位数。 Emacs表示一个整数 如果超出此限制,则会发生溢出错误。
以前有几个原始函数返回浮点数或列表 整数,表示不适合fixnums的整数。这些 函数现在仅返回整数。受影响的功能 包括诸如“ encode-char”之类的用于计算代码点的函数 例如计算文件大小和其他属性的“文件属性”, 像'process-id'这样的函数来计算进程ID,而像 计算用户和组ID的“ user-uid”和“ group-gid”。
并确实使用我的27.0.50版本:
(defun square (x) (* x x))
square
(square (square (square 1001)))
1008028056070056028008001