2012-01-18 10 views
4

この質問はeuler project sum-of-primes, and Stream.viewに関連していますが、少し捻りがあります。私は200万以下のすべての素数の合計を計算したいと思います。Scala Stream [Int] #foldLeftとStream [Int] #sumは異なる結果を返します

@Test 
def testEuler010a { 
    primes.view.takeWhile(_ < 2000000).foldLeft(0L)(_ + _) mustEqual 142913828922L 
} 

@Test 
def testEuler010b { 
    primes.view.takeWhile(_ < 2000000).sum mustEqual 142913828922L 
} 

testEuler010aは私を与える:私はストリーム[INT] #sumを使用して、2回の試験では、1ストリーム[INT] #foldLeftを使用し、1を書いた

lazy val primes: Stream[Int] = 2 #:: Stream.from(3).filter(i => 
    primes.takeWhile(j => j * j <= i).forall(i % _ > 0)) 

:私は以下のように定義素数のジェネレータを作成しますtestEuler010bの回答は1179908154ではありません。私はStream[Int]#foldLeft(0L)(_ + _)Stream[Int].sumと同じであると期待しますが、そうではありません。 toList()でStreamを具体化しても、同じ矛盾が生じます。それらのメソッドが同じ結果を与えるべきであるという誤った仮定ですか?

私はScala 2.9.1.finalを使用しています。

+0

私の 'view'の使用は必要ありません。この場合パフォーマンスが改善されず、別の結果が得られません。 – andyczerwonka

+3

'142913828922L%(Int.MaxValue.toLong + 1)'は 'sum'バージョンが与える値と等しいことに注意してください。 –

答えて

11

問題はオーバーフローのようです。これらは、私のために同じ結果を与える:

(primes map (_.longValue) takeWhile (_ < 2000000)).sum 
(primes map (_.longValue) takeWhile (_ < 2000000)).foldLeft(0L)(_ + _) 

私はsumfoldLeftとの違いは、(Numeric traitで必要とされる)sumの結果タイプがにわたって合計されている要素の型と同じであるということであると仮定し、 foldLeftは異なる結果タイプを持つことができます。これは0Lと書いてください。

関連する問題