2009-10-28 19 views
5

Na 2.7.5.final, jestem próbuje dodać Iterable listę Ints jak takScala: Przepełnienie mimo stosowania długich podczas dodawania

def sum(xs: Iterable[Int]): Long = { 
    var sum = 0L 
    xs.foreach((x) => sum = sum + x) 
    sum 
} 

println(sum(List(1, Integer.MAX_VALUE - 1))) 
println(sum(Integer.MAX_VALUE - 1 to Integer.MAX_VALUE)) 
println(0L + Integer.MAX_VALUE - 1 + Integer.MAX_VALUE) 

Kiedy biegnę, mam

2147483647 
0 
4294967293 

Można też powiedzieć "use reduceLeft (_ + _)", ale wydaje się, że można zwrócić tylko ten sam typ, co elementy na liście ... ale chcę akumulować na Long, więc nie mogę " • mają problemy z przepełnieniem.

Aktualizacja 2009-10-28

Jest to błąd w zasięgu, jak podkreślił Eastsun. Został zgłoszony zespołowi Scala pod numerem ticket 2535

+0

Hmm, println (suma (List (Integer.MAX_VALUE - 1, Integer.MAX_VALUE))) daje 4294967293. To ma coś wspólnego z metodą 'na' ja podejrzanego. Interesujące pytanie! –

Odpowiedz

7

To błąd w Range. Nie jest kod źródłowy metody foreach Zakres za:

override def foreach(f: Int => Unit) { 
if (step > 0) { 
    var i = this.start 
    *val until = if (inInterval(end)) end + 1 else end*  //bug here!!! 

    while (i < until) { 
    f(i) 
    i += step 
    } 
} else { 
    var i = this.start 
    val until = if (inInterval(end)) end - 1 else end 

    while (i > until) { 
    f(i) 
    i += step 
    } 
} 

}

+0

Wygląda na to, że ten błąd istnieje w Scala2.7.x i obecnej wersji Scala 2.8.x. – Eastsun

+0

Czy ktoś podniósł ten błąd w Scala Trac? –

+0

Jeszcze nie (o ile mi wiadomo) – Eastsun

5

Eastsun „s odpowiedź dał bardzo dobry powód, dla którego przelewa obliczeniowe. W celu obejścia tego problemu zdefiniowałbym ponownie funkcję sum w celu użycia foldLeft, która pozwala określić akumulator.

def sum(xs: Iterable[Int]): Long = 
    xs.foldLeft(0L)(_ + _) 

lub stosując skrót od foldLeft (który Lubię ponieważ stawia wartość początkową owczarni przed Iterable próbujesz krotnie).

def sum(xs: Iterable[Int]): Long = 
    (0L /: xs)(_ + _) 

W obu przypadkach kod, który próbowano uruchomić, daje prawidłowe wyniki.

- Flaviu Cipcigan

Powiązane problemy