【问题标题】:Lisp interactive emacs multiplying incorrectlyLisp 交互式 emacs 乘法不正确
【发布时间】:2019-03-14 01:28:59
【问题描述】:

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

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

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

【问题讨论】:

    标签: emacs numbers lisp elisp bignum


    【解决方案1】:

    @Barmar 的回答对于 Emacs

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

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

    所有算术、比较和逻辑(又名“按位”) bignums 有意义的操作现在支持 fixnums 和 大名鼎鼎。但是,请注意,与 fixnums 不同,bignums 不会比较 等于 'eq',你必须使用 'eql' 代替。 (数值比较 当然,'=' 对两者都有效。)

    由于大的 bignums 会消耗大量内存,Emacs 会限制 Lisp 程序允许创建的最大 bignum。这 新变量“整数宽度”的非负值指定 bignum 中允许的最大位数。 Emacs 表示一个整数 如果超出此限制,则会出现溢出错误。

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

    确实使用了我的 27.0.50 版本:

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

    【讨论】:

    • 我有十分钟的时间盯着我的 Emacs 26 实例想知道为什么会出现溢出错误。感谢您确保注意这仅适用于 27 岁以上。
    【解决方案2】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-24
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多