Mike Vella
Mike Vella

Reputation: 10575

Recursive function (factorial) breaks Clojure with IntOverflow but not Python

I define a recursive function in the same way in both Clojure and Python:

;;;Clojure:
(defn factorial [n]
  (if (< n 1)
    1
    (* n (factorial (- n 1)))))

#Python:
def factorial(n):
    if n<1:
        return 1
    else:
    return n*factorial(n-1)

In Python if I run factorial(200) I get:

788657867364790503552363213932185062295135977687173263294742533244359449963403342920304284011984623904177212138919638830257642790242637105061926624952829931113462857270763317237396988943922445621451664240254033291864131227428294853277524242407573903240321257405579568660226031904170324062351700858796178922222789623703897374720000000000000000000000000000000000000000000000000L

In Clojure I get:

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

What is it about Clojure on the JVM that is causing such an integer overflow when Python is happy to deal with this function? I have read around this problem and it seems related the fact that Python can produce long integers which are only restricted by available memory whereas I guess Clojure can't - but I would appreciate some more detail of exactly what's going on.

Upvotes: 2

Views: 226

Answers (1)

Jeremy
Jeremy

Reputation: 22435

By default, Clojure uses JVM Longs to represent integers, so the range is from -2^63 to 2^(63-1).

In order to use arbitrary precision in Clojure, you can use the +', *', -', inc', and dec' versions of the given operators.

Upvotes: 7

Related Questions