Lisp交互式emacs错误地成倍增加

问题描述 投票:0回答:2

我在Emacs Lisp Interaction上运行以下代码:

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

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

emacs numbers lisp elisp bignum
2个回答
9
投票

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

9
投票

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

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

** Emacs Lisp整数现在可以是任意大小。 Emacs使用GNU Multiple Precision(GMP)库来支持大小太大而无法原生支持的整数。本机支持的整数称为“fixnums”,而较大的整数称为“bignums”。新谓词'bignump'和'fixnump'可用于区分这两种类型的整数。

bignums有意义的所有算术,比较和逻辑(a.k.a。“按位”)操作现在都支持fixnums和bignums。但请注意,与fixnums不同,bignums不会与'eq'进行比较,您必须使用'eql'。 (当然,与'='的数值比较对两者都有效。)

由于大型bignums消耗大量内存,因此Emacs限制了允许Lisp程序创建的最大bignum的大小。新变量“integer-width”的非负值指定了bignum中允许的最大位数。如果超出此限制,Emacs会发出整数溢出错误信号。

以前的几个原始函数返回浮点数或整数列表来表示不适合fixnums的整数。这些函数现在只返回整数。受影响的函数包括计算代码点的'encode-char',计算文件大小和其他属性的'文件属性'等函数,计算进程ID的'process-id'等函数,以及'user-uid等函数'和'group-gid'计算用户和组ID。

并确实使用我的27.0.50版本:

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

(square (square (square 1001)))
1008028056070056028008001
© www.soinside.com 2019 - 2024. All rights reserved.