2012-01-18 4 views
4

이 질문은 euler project sum-of-primes, and Stream.view과 관련이 있지만 다소 비뚤어졌습니다. 2 백만 밑에 모든 소수의 합을 계산하고 싶습니다.스칼라 스트림 [정수] #foldLeft 및 스트림 [Int] #sum 결과가 다릅니다.

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

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

testEuler010a 저를 준다 : 나는 스트림 [지능] #sum을 사용하여 두 테스트, 하나의 스트림 [지능] #foldLeft를 사용하여 하나를 썼다

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

: I는 다음과 같이 정의 된 소수의 발전기를 만들 대답은 testEuler010b이고 대답은 1179908154입니다. Stream[Int]#foldLeft(0L)(_ + _)Stream[Int].sum과 동일 할 것으로 예상되지만 그렇지 않습니다. toList()으로 스트림을 구체화하더라도 동일한 불일치가 발생합니다. 그러한 방법이 동일한 결과를 가져야한다는 잘못된 가정입니까?

저는 스칼라 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)(_ + _) 

I가 sumfoldLeft 차이합니다 (Numeric trait 필요) sum 결과 유형 합산되는 원소의 종류와 동일하다고 가정하자, foldLeft은 다른 결과 유형을 가질 수 있으며, 이는 0L으로 작성합니다.