Recursion Clojure-Koan阶乘函数实现

Recursion Clojure-Koan阶乘函数实现,recursion,clojure,Recursion,Clojure,我正在学习clojure并完成练习。其中一个练习是关于。当我四处玩耍时,我注意到: 我的递归实现似乎适用于大量数据: (defn factorial-1 [n] (loop [n n f 1] (if (= n 1) f (recur (dec n) (* f n))))) 在REPL中调用(factorial-1 1000N)会产生一个数字:402387260077093773… 但是,当我尝试以下惰性序列方法时: (defn fac

我正在学习clojure并完成练习。其中一个练习是关于。当我四处玩耍时,我注意到:

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

(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)

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

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

(defn factorial-2 [n]
  (reduce * 1N (range 1 (inc n))))
或者您可以简单地使用函数

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

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

,感谢您提供的更多信息!我没有意识到
reduce
的初始值类型会改变行为。很有趣。我不知道这个功能。我假设在
clojure.core
名称空间中存在此函数,这会使clojure更加惯用。