On 2.7.5.final, I'm attempting to add a Iterable list of Ints like so
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 run, I get
2147483647
0
4294967293
And, you might say "use reduceLeft(_ + _)", but it seems to only be able to return the same type as elements in the list... but I want to accumulate to a Long, so I don't have overflow issues.
Update 2009-10-28
This is a bug in Range, as pointed out by Eastsun. It's been reported to the Scala team in ticket 2535
The value is too big for an int or double variable in Java, and there will be an overflow.
In languages where integer overflow can occur, you can reduce its likelihood by using larger integer types, like Java's long or C's long long int. If you need to store something even bigger, there are libraries built to handle arbitrarily large numbers.
"A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."
An integer overflow occurs when you attempt to store inside an integer variable a value that is larger than the maximum value the variable can hold. The C standard defines this situation as undefined behavior (meaning that anything might happen).
It's a bug of Range. There is the source code of Range's foreach method:
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
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With