使用Clojure中的延迟序列进行整数溢出

时间:2012-06-25 20:34:53

标签: clojure lazy-evaluation integer-overflow

我只是学习在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,那么导致整数溢出的原因是什么?

2 个答案:

答案 0 :(得分:5)

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

修复此用途+'而不是

你的第100个纤维蛋白数对于整数来说太大了

user> (nth (fib) 100)
354224848179261915075N

答案 1 :(得分:5)

过滤无限seq会产生无限seq并减少此值会导致过滤器在谓词停止返回true后仍继续寻找另一个匹配项。

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

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

(sum (up-to 100 (fib))) ;; => 232