Scala: overflow despite using Long when adding

In 2.7.5.final, I am trying to add a list of Iterable Ints, for example,

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)

When I get in, I get

2147483647
0
4294967293

And you can say "use reduceLeft (_ + _)", but it looks like it can return the same type as the items in the list ... but I want to accumulate before Long, so I don’t have Overflow problems.

Update 2009-10-28

This is a mistake in Range, as Eastsun points out. Reported to Scala Team on Ticket 2535

+5
source share
2 answers

This is a Range error. The source code for the Range foreach method exists:

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
  }
}

}

+7
source
Answer

Eastsun , . sum foldLeft, .

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

foldLeft ( , Iterable, ).

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

, , .

-

+5

All Articles