这是一个使用尾部递归的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代码有什么问题?
最佳答案
没什么,只需要使用BigInt
即可:
(factorial 1N 30N) ;=> 265252859812191058636308480000000N
参数可能很小,但结果却不是!
请注意,也提供了滴答版本的算术运算符,它们支持任意精度:
(reduce *' (range 1 31)) ;=> 265252859812191058636308480000000N
关于recursion - Clojure中的尾递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16655548/