我试图让第一个 lisp 程序使用 CLISP 实现工作,通过键入
(print (mod (+ (* 28433 (expt 2 7830457) 1)) (expt 10 10))))
在 REPL 中。
但它给了我*** - overflow during multiplication of large numbers
。我认为 lisp 具有任意大小/精度。那怎么会发生呢?
我试图让第一个 lisp 程序使用 CLISP 实现工作,通过键入
(print (mod (+ (* 28433 (expt 2 7830457) 1)) (expt 10 10))))
在 REPL 中。
但它给了我*** - overflow during multiplication of large numbers
。我认为 lisp 具有任意大小/精度。那怎么会发生呢?
Lisp 的 bignums 可能包含非常大的数字,但它们也有其局限性。
在您的情况下,您可以将求幂和模数组合到一个过程中,例如http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method。
有可能有更好的方法来解决问题。我在 PE 上还没有做到那么远,但我知道我到目前为止所做的少数人往往会“啊哈!” 似乎超出计算机程序范围的问题的解决方案。
尤其是这个 - 2^7830457 是一个巨大的数字 - 试试看(format t "~r" (expt 2 160))
。您可能会尝试以新的眼光看待问题,看看是否有一种您没有想到的方法来看待它。
根据http://clisp.cons.org/impnotes/num-concepts.html,bignum的最大尺寸为 (2^2097088 - 1),而您的 2^7830457 比这大得多。
也许你可以看看分解这个数字 - 也许分离出一些较小的 2^X 因子......
Lisp 是一个拥有数十种方言和数百种不同实现的语言家族。
计算机的内存是有限的。某些操作系统下的程序可能对内存大小有限制。不同的 Common Lisp 实现使用不同的数值库。
您可能需要查阅 CLISP 手册以了解其各种数据类型的限制。
CLisp 提供了函数“mod-expt”(或 EXT:mod-expt)
[1]> (mod-expt 2 1000000 59)
53
这是相当快的。并且为了你的目的。