2009-10-28 23 views
5

On 2.7.5.final, tôi đang cố gắng để thêm một danh sách Iterable của Ints như vậyScala: tràn mặc dù sử dụng lâu khi thêm

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) 

Khi tôi chạy, tôi nhận được

2147483647 
0 
4294967293 

Và, bạn có thể nói "sử dụng reduceLeft (_ + _)", nhưng dường như chỉ có thể trả về cùng loại với các phần tử trong danh sách ... nhưng tôi muốn tích lũy thành Long, vì vậy tôi không ' t có vấn đề tràn.

Cập nhật 2009-10-28

Đây là một lỗi trong phạm vi, như đã chỉ ra bởi Eastsun. Báo cáo này được báo cáo cho nhóm Scala theo số ticket 2535

+0

Hmm, println (sum (Danh sách (Integer.MAX_VALUE - 1, Integer.MAX_VALUE))) mang 4294967293. này có cái gì để làm với các 'thành' phương pháp tôi nghi ngờ. Câu hỏi thú vị! –

Trả lời

7

Đó là lỗi của Phạm vi. Có mã nguồn của phương pháp foreach Range:

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

Dường như lỗi này tồn tại trong Scala2.7.x và Scala 2.8.x. – Eastsun

+0

Có ai nêu lỗi này trong Scala Trac không? –

+0

Chưa (theo như tôi biết) – Eastsun

5

Eastsun 's câu trả lời đã đưa ra một lý do rất chính đáng tại sao bạn tràn tính toán. Để khắc phục sự cố, tôi sẽ xác định lại chức năng sum để sử dụng foldLeft, cho phép bạn chỉ định bộ tích lũy.

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

hoặc sử dụng viết tắt cho foldLeft (mà tôi rất thích vì nó đặt giá trị ban đầu của nếp gấp ở phía trước của Iterable bạn đang cố gắng gấp).

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

Trong cả hai trường hợp, mã bạn đang cố gắng chạy đều cho kết quả chính xác.

- Flaviu Cipcigan

Các vấn đề liên quan