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

clojure 1.3.0以降の数値は、bigInt/bigDecimalに自動昇格しません。

+'代わりにこの使用法を修正するには

100番目のフィビナチ数が整数に対して大きすぎます

user> (nth (fib) 100)
354224848179261915075N
于 2012-06-25T20:59:28.813 に答える
5

無限のseqをフィルタリングすると、無限のseqが生成されます。これを減らすと、述語がtrueを返さなくなった後でも、フィルターは別の一致する項目を探し続けます。

に置き換えfilterますtake-while。によって生成された無限のシーケンスは永久に実行され(fib)ますが、その前に、あなたが経験filterしているために壊れます。述語がfalseと評価された後、リストのそれ以上の評価を停止します。ArithmeticExceptiontake-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 に答える