StackOverFlow in Clojure even when I am using bigint

时间:2015-11-12 11:09:55

标签: clojure biginteger

I am using the below code to find the factorial.

(defn factorial [x]
  (if (< x 2)
    1N
    (*' (factorial (- x 1)) x)))

I am using the bigint operations *' and -' but even after that I am getting stackoverflow errors when I am calling it using 5500 and above.

StackOverflowError   clojure.lang.Numbers$LongOps.combine (Numbers.java:419)
user=> (factorial 5300)

StackOverflowError   clojure.lang.Numbers$LongOps.add (Numbers.java:455)
user=> (factorial 5300)

I have looked at other questions but they say that using these operations should give me correct answer. So what am I missing here?

I am learning Clojure so this is a learning exercise.

1 个答案:

答案 0 :(得分:5)

The StackOverflowError occurs because factorial invokes itself recursively. Large numbers of x expand into too many nested factorial invocations, causing the stack to overflow.

You should rewrite your function to use loop/recur instead of recursive invocations:

(defn factorial [n]
  (loop [cnt n acc 1N]
     (if (zero? cnt)
        acc
        (recur (dec cnt) (*' acc cnt)))))