简体   繁体   English

在clojure中的尾递归

[英]Tail recursion in clojure

This is a lisp code that uses tail recursion. 这是一个使用尾递归的lisp代码。

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

I translate this into clojure code expecting the same tail recursion optimization. 我把它翻译成clojure代码,期望相同的尾递归优化。

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

However I got this integer overflow (not stack overflow) even with small number such as (fact 1 30) . 但是我得到了这个整数溢出(不是堆栈溢出),即使是很少的数字,如(fact 1 30)

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

I tried with recur , but got the same error. 我试过recur ,但得到了同样的错误。

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

What's wrong with the clojure code? clojure代码有什么问题?

Nothing, just use BigInt s: 没什么,只需使用BigInt

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

The arguments may be small, but the result is not! 参数可能很小,但结果却不是!

Note that ticked versions of the arithmetic operators are also available, which support arbitrary precision: 请注意,算术运算符的勾选版本也可用,它支持任意精度:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM