2009-10-28 9 views
5

2.7.5.final पर जोड़ने, मैं इतनास्काला: लंबे के उपयोग के बावजूद अतिप्रवाह जब

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) 

जब मैं चलाने के लिए, मैं

2147483647 
0 
4294967293 
मिल की तरह Ints की एक Iterable सूची में जोड़ने का प्रयास कर रहा हूँ

और, आप कह सकते हैं "कम करें Left (_ + _)" का उपयोग करें, लेकिन ऐसा लगता है कि सूची में तत्वों के रूप में केवल उसी प्रकार को वापस करने में सक्षम हो सकता है ... लेकिन मैं लंबे समय तक जमा करना चाहता हूं, इसलिए मैं ' टी ओवरफ्लो मुद्दे है।

अद्यतन 2009-10-28

इस रेंज में एक बग, के रूप में Eastsun से बताया है। यह ticket 2535

+0

हम्म, println (राशि (सूची (Integer.MAX_VALUE - 1, Integer.MAX_VALUE))) पैदावार 4294967293. यह 'को' विधि मुझे लगता है के साथ क्या करने के लिए कुछ नहीं है। दिलचस्प सवाल! –

उत्तर

7

में स्कैला टीम को रिपोर्ट किया गया है यह रेंज का एक बग है। वहाँ रेंज के foreach विधि के स्रोत कोड है:

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

ऐसा लगता है कि यह बग Scala2.7.x और वर्तमान स्कैला 2.8.x में मौजूद है। – Eastsun

+0

क्या किसी ने भी इस बग को स्कैला ट्रैक में उठाया है? –

+0

अभी तक नहीं (जहां तक ​​मुझे पता है) – Eastsun

5

Eastsun के जवाब एक बहुत अच्छा कारण है कि आप गणना अतिप्रवाह दे दी है। एक वर्कअराउंड के रूप में मैं फ़ंक्शन को foldLeft का उपयोग करने के लिए फिर से परिभाषित करता हूं, जो आपको संचयक निर्दिष्ट करने की अनुमति देता है।

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

या foldLeft के लिए आशुलिपि का उपयोग कर (जो मैं काफी यह Iterable आप गुना करने के लिए कोशिश कर रहे हैं के सामने गुना का प्रारंभिक मूल्य कहते हैं) की तरह।

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

दोनों मामलों में, जिस कोड को आप चलाने की कोशिश कर रहे थे वह सही परिणाम देता है।

- Flaviu Cipcigan

संबंधित मुद्दे