Clojure Koan因子函数实现

时间:2015-11-09 22:27:47

标签: recursion clojure

我正在学习clojure并进行clojure-koan练习。其中一个练习是implementing a factorial function。我在玩的时候注意到了:

我的递归实现似乎适用于大数字:

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

在REPL中调用(factorial-1 1000N)会产生一个数字:402387260077093773...

然而,当我尝试以下懒惰序列方法时:

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

在REPL中调用(factorial-2 1000N)会产生错误:

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

为什么看似懒惰的序列方法会导致整数溢出错误?

2 个答案:

答案 0 :(得分:8)

尽管传递了1000N,但您实际上从未在乘法中使用任何bigint,因为您只使用该数字来确定计算的 end 。您可以在1处开始乘法,然后乘以1,然后乘以2,依此类推。如果您修改factorial-2的定义以使用bigint,则会得到预期的行为:

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

答案 1 :(得分:4)

或者您只需使用*'功能。

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

*'函数支持任意精度。如果数字在Long范围内,它将返回Long。如果范围超出长范围,它将返回BigInt