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

Che*_*tan 8 clojure integer-overflow lazy-evaluation

我只是学习在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)
Run Code Online (Sandbox Code Playgroud)

求和的数字不应大于100,那导致整数溢出的原因是什么?

Art*_*ldt 5

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

解决这个问题的使用+',而不是

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

user> (nth (fib) 100)
354224848179261915075N
Run Code Online (Sandbox Code Playgroud)


Jan*_*Jan 5

过滤无限seq会产生无限seq,并且减少此值会导致过滤器继续查找另一个匹配项,即使谓词停止返回true也是如此.

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

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

(sum (up-to 100 (fib))) ;; => 232
Run Code Online (Sandbox Code Playgroud)

  • 没关系,我明白了......这不是过滤器本身.过滤无限seq会产生无限seq,并且减少此值会导致过滤器在谓词停止返回true后仍继续寻找另一个匹配项. (3认同)