在clojure中的尾递归

pro*_*eek 10 recursion tail-recursion clojure

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

(defun factorial (f n)
    (if (= n 1)
        f
        (factorial (* f n) (- n 1))))
Run Code Online (Sandbox Code Playgroud)

我把它翻译成clojure代码,期望相同的尾递归优化.

(defn fact [f n]
    (if (= n 1)
        f
        (fact (* f n) (dec n))))
Run Code Online (Sandbox Code Playgroud)

但是我得到了这个整数溢出(不是堆栈溢出),即使是很小的数字,如(fact 1 30).

ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)
Run Code Online (Sandbox Code Playgroud)

我尝试过recur,但得到了同样的错误.

(defn factorial [f n]
    (if (= n 1)
        f
        (recur (* f n) (dec n))))
Run Code Online (Sandbox Code Playgroud)

clojure代码有什么问题?

A. *_*ebb 18

没什么,只是用BigInts:

(factorial 1N 30N) ;=> 265252859812191058636308480000000N
Run Code Online (Sandbox Code Playgroud)

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

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

(reduce *' (range 1 31)) ;=> 265252859812191058636308480000000N
Run Code Online (Sandbox Code Playgroud)