【问题标题】:CLISP overflow after multiplication乘法后 CLISP 溢出
【发布时间】:2011-03-11 05:50:46
【问题描述】:

我正在尝试让第一个 lisp 程序使用 CLISP 实现工作,通过键入

(print (mod (+ (* 28433 (expt 2 7830457) 1)) (expt 10 10))))

在 REPL 中。

但它给了我*** - overflow during multiplication of large numbers。我认为 lisp 具有任意大小/精度。那怎么会发生呢?

【问题讨论】:

  • 或者编译它会以某种方式解决这个问题?
  • 另外,它可能关心的人,这是欧拉项目的第 97 个问题 :)

标签: lisp read-eval-print-loop clisp


【解决方案1】:

Lisp 的 bignums 可能包含非常大的数字,但它们也有其局限性。

在您的情况下,您可以将求幂和模数组合到一个过程中,例如如http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method

【讨论】:

    【解决方案2】:

    根据http://clisp.cons.org/impnotes/num-concepts.html,bignum 的最大大小为 (2^2097088 - 1),而您的 2^7830457 比这大得多。

    也许您可以查看分解该数字 - 或许分离出一些较小的 2^X 因子...

    【讨论】:

    • 看起来 bignums 以 4 字节字的数字长度存储 2 个字节。我想知道将长度扩展到 3 或 4 个字节需要什么。
    【解决方案3】:

    可能有更好的方法来解决问题。我在 PE 上还没有做到那么远,但我知道我到目前为止所做的少数人往往会“啊哈!”解决似乎超出计算机程序范围的问题。

    尤其是这个 - 2^7830457 是一个 巨大 的数字 - 试试 (format t "~r" (expt 2 160))。您可能会尝试以新的眼光看待问题,看看是否有一种您没有想到的方法来看待它。

    【讨论】:

      【解决方案4】:

      Lisp 是一个拥有数十种方言和数百种不同实现的语言家族。

      计算机的内存是有限的。某些操作系统下的程序可能对内存大小有限制。不同的 Common Lisp 实现使用不同的数值库。

      您可能需要查阅 CLISP 手册,了解其对各种数据类型的限制。

      【讨论】:

        【解决方案5】:

        CLisp 提供了函数“mod-expt”(或 EXT:mod-expt)

        [1]> (mod-expt 2 1000000 59)
        
        53
        

        这是相当快的。并且为了您的目的。

        【讨论】:

          猜你喜欢
          • 2014-05-21
          • 2015-08-16
          • 2015-04-11
          • 2015-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多