在clojure中的尾递归

时间:2013-05-20 18:06:00

标签: recursion clojure tail-recursion

这是一个使用尾递归的lisp代码。

(defun factorial (f n)
    (if (= n 1)
        f
        (factorial (* f n) (- n 1))))

我将此转换为clojure代码,期望进行相同的尾递归优化。

(defn fact [f n]
    (if (= n 1)
        f
        (fact (* f n) (dec n))))

然而,即使用(fact 1 30)这样的小数字,我也得到了这个整数溢出(不是堆栈溢出)。

ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)

我尝试使用recur,但遇到了同样的错误。

(defn factorial [f n]
    (if (= n 1)
        f
        (recur (* f n) (dec n))))

clojure代码有什么问题?

1 个答案:

答案 0 :(得分:18)

没什么,只需使用BigInt s:

(factorial 1N 30N) ;=> 265252859812191058636308480000000N

参数可能很小,但结果不是!

请注意,算术运算符的勾选版本也可用,它们支持任意精度:

(reduce *' (range 1 31)) ;=> 265252859812191058636308480000000N