Recursion Clojure-Koan阶乘函数实现
我正在学习clojure并完成练习。其中一个练习是关于。当我四处玩耍时,我注意到: 我的递归实现似乎适用于大量数据: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
(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更加惯用。