8

我刚刚学习在 Clojure 中使用惰性序列,我不确定我在以下代码中做错了什么:

(defn sum [seqn]
  (reduce + seqn))

(defn fib
  ([] (concat [0 1] (fib 0 1)))
  ([a b] (lazy-seq (cons (+ a b) (fib b (+ a b))))))

(defn up-to [n seqn]
  (filter (fn [x] (< x n)) seqn))

(sum (up-to 100 (fib))) => ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)

相加的数字不应大于100,那么是什么导致整数溢出?

4

2 回答 2

5

过滤一个无限序列会产生一个无限序列,并且减少它会导致过滤器继续寻找另一个匹配项,即使在谓词停止返回 true 之后也是如此。

替换filtertake-while。生成的无限序列(fib)将导致filter永远运行,但在此之前它将因ArithmeticException您正在经历而中断。在谓词评估为假take-while后,将停止对列表的进一步评估。(fn [x] (< x n))

(defn up-to [n seqn]
  (take-while (fn [x] (< x n)) seqn))

(sum (up-to 100 (fib))) ;; => 232
于 2012-06-25T21:03:32.473 回答
5

从 clojure 1.3.0 开始,数字不会自动升级为 bigInt/bigDecimal。

+'改为修复此用途

你的第 100 个 fibinachi 数字对于整数来说太大了

user> (nth (fib) 100)
354224848179261915075N
于 2012-06-25T20:59:28.813 回答