Clojure Koan因子函数实现

ind*_*iel 5 recursion clojure

我正在学习clojure并经历了clojure-koan练习.其中一个练习是关于实现阶乘功能.我在玩的时候注意到:

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

(defn factorial-1 [n]
   (loop [n n f 1]
      (if (= n 1)
          f
          (recur (dec n) (* f n)))))
Run Code Online (Sandbox Code Playgroud)

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

但是,当我尝试以下懒惰序列方法时:

(defn factorial-2 [n]
   (reduce * 1 (range 1 (inc n))))
Run Code Online (Sandbox Code Playgroud)

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

ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)
Run Code Online (Sandbox Code Playgroud)

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

ama*_*loy 8

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

(defn factorial-2 [n]
  (reduce * 1N (range 1 (inc n))))
Run Code Online (Sandbox Code Playgroud)


nta*_*lbs 5

或者你可以简单地使用*'函数。

(defn factorial-3 [n]
  (reduce *' (range 1 (inc n))))
Run Code Online (Sandbox Code Playgroud)

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