Clojure Implementation of the Koan factorial function

I learn clojure and look through the clojure -koan exercises. One exercise is the implementation of a factorial function . When I played, I noticed:

The recursive implementation seems to work for large numbers:

(defn factorial-1 [n] (loop [nnf 1] (if (= n 1) f (recur (dec n) (* fn))))) 

The call (factorial-1 1000N) in the REPL gives the number: 402387260077093773...

However, when I try to use the following lazy approach:

 (defn factorial-2 [n] (reduce * 1 (range 1 (inc n)))) 

Calling (factorial-2 1000N) in REPL gives an error:

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

Why does the seemingly lazy sequence approach lead to an integer overflow error?

+5
source share
2 answers

Or you can just use the *' function.

 (defn factorial-3 [n] (reduce *' (range 1 (inc n)))) 
Function

*' supports arbitrary precision. It will return Long if the number is in the Long range. If the range exceeds a long range, it will return BigInt .

+4
source

In fact, you never use any bandages in your multiplications, despite the fact that you skip 1000N, because you only use this number to determine the end of your calculation. You start multiplying by 1 and multiplying by 1 , then 2 , etc. If you change the definition of factorial-2 to use bigint, you get the expected behavior:

 (defn factorial-2 [n] (reduce * 1N (range 1 (inc n)))) 
+8
source

Source: https://habr.com/ru/post/1235575/


All Articles