Clojure's implementation of number types builds on the host platform's number types. Your solution works when you define the arbitrary size flag N
, because the underlying number type changes on the JVM.
(type 10) ;=> java.lang.Long
(type 10N) ;=> clojure.lang.BigInt
clojure.lang.BigInt
uses either java.math.BigInteger
or a Java long
as the underlying type, depending on the bit size of the number.
On a different host, the Javascript engine of a browser, both types are JavaScript's native Number
s. The factorial
function gives a result up to 170 in ClojureScript. It does not throw when overflowing, but returns the JavaScript number value Infinity:
(factorial 170) ; => 7.257415615307994e+306
(factorial 170N) ; => 7.257415615307994e+306
(factorial 171N) ; => Infinity
Update: This answer (pointed out by @cske) gives a neat solution to use the *'
operator, which bumps up the number type in case it would overflow:
(defmethod factorial :default [num]
(*' num (factorial (dec num))))
(factorial 40) ; => 815915283247897734345611269596115894272000000000N