给定n位整数和m位整数。如何使用列表,数组或任何其他特定于lisp的数据类型在LISP中将它们相乘?
例如;
一(1)(2)... A(N)
b(1)b(2)... b(m)
结果为;
R(1)R(2)... R(M + N)
答案 0 :(得分:6)
Common Lisp本身已经bignums。你为什么不用它们?
你基本上不必特别声明任何东西,它们“神奇地”发生:
% sbcl
This is SBCL 1.0.56.0.debian, an implementation of ANSI Common Lisp.
* (defun fact (n) (if (< n 1) 1 (* n (fact (- n 1)))))
FACT
* (fact 50)
30414093201713378043612608166064768844377641568960512000000000000
所以使用Common Lisp,你基本上不必费心......
高效的bignum算法是一个非常困难的问题;高效的算法比天真的算法具有更好的复杂性;你可以找到解释它们的困难书籍(基础数学很难)。另请参阅this answer。
如果你想要有竞争力的bignum实施,准备好工作几年,并使其成为博士论文。
答案 1 :(得分:4)
一个简单的算法就是模仿手工计算多重复制时所做的事情:
123 x
456 =
---
738
615
492
-----
56088
第一步是通过单个“数字”(例如123 x 6 = 738
)实现乘法。
在您完成移位之后当然是微不足道的(只是列表中的滑动元素),因此可以使用您的加法函数完成乘法。
请注意,这不是计算两个大数字乘积的最快方法(例如,请参阅Karatsuba algorithm)。
PS:思考如何用手计算两个大数的乘积也解释了一些“惊人的”结果,如111111111 * 111111111 = 12345678987654321 111111111 x
111111111 =
---------
111111111
111111111
111111111
111111111
111111111
111111111
111111111
111111111
111111111
-----------------
12345678987654321
答案 2 :(得分:3)
(* 1234567890123456789123456789 1234567890123456789123456789)
Big ints是Common Lisp的原生。