zen*_*god 0 lisp emacs elisp numbers bignum
我在Emacs Lisp Interaction上运行以下代码:
(defun square (x) (* x x))
(square (square (square 1001)))
Run Code Online (Sandbox Code Playgroud)
这给了我1114476179152563777
。但是,((1001^2)^2)^2
实际上是1008028056070056028008001
。这怎么可能?
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
Run Code Online (Sandbox Code Playgroud)
@Barmar的答案对于<27的Emacs版本是正确的。
在Emacs 27 bignum支持已添加。新闻说:
** Emacs Lisp整数现在可以是任意大小。Emacs使用GNU多精度(GMP)库来支持整数,该整数的大小太大而无法原生支持。本机支持的整数称为“ fixnums”,较大的整数为“ bignums”。新的谓词“ bignump”和“ fixnump”可用于区分这两种类型的整数。
现在,bignums有意义的所有算术,比较和逻辑(也称为“按位”)操作都支持fixnums和bignums。但是,请注意,与fixnums不同,bignums不会与'eq'相等,而必须使用'eql'。(当然,在数值上用'='进行比较)。
由于大型bignum占用大量内存,因此Emacs限制了允许Lisp程序创建的最大bignum的大小。新变量'integer-width'的非负值指定bignum中允许的最大位数。如果超出此限制,Emacs将发出整数溢出错误信号。
多个原始函数以前返回浮点数或整数列表,以表示不适合fixnums的整数。这些函数现在仅返回整数。受影响的函数包括计算代码点的“ encode-char”之类的函数,计算文件大小和其他属性的“ file-attributes”之类的函数,计算进程ID的“ process-id”之类的功能以及“ user-uid”之类的功能。 '和'group-gid'来计算用户和组ID。
并确实使用我的27.0.50构建:
(defun square (x) (* x x))
square
(square (square (square 1001)))
1008028056070056028008001
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
99 次 |
最近记录: |