recursion - Clojure中的尾递归

标签 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代码有什么问题?

最佳答案

没什么,只需要使用BigInt即可:

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

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

请注意,也提供了滴答版本的算术运算符,它们支持任意精度:
(reduce *' (range 1 31)) ;=> 265252859812191058636308480000000N

关于recursion - Clojure中的尾递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16655548/

相关文章:

python - 在函数式编程(或其他方式)中递归时,使用显式状态变量的好处/限制是什么?

java - 是什么导致我的代码中出现 StackoverFlowError?

java - Java中使用数组的二叉搜索树

clojure - 在宏中正确处理符号解析

haskell - Haskell 有尾递归优化吗?

mysql - 如何在 MySQL 中创建递归存储过程?

emacs - 我如何在 emacs 中找到 clojure 符号的所有引用?

authentication - 如何让 Swagger UI 让我提供身份验证 header ?

javascript - ES6 类中的递归方法是否利用了 TCO(尾部调用优化)?

这个阿克曼函数的实现可以称为尾递归吗?