2013-08-20 6 views
7

Also, gestern während der Arbeit durch einige F # Code als Teil einer Codierung Übung, zeigte ein anderer Entwickler etwas Interessantes. Wir haben nur einen kurzen Code geschrieben, um die Zusammenfassung einer Liste zu demonstrieren. Wenn ich das tue:How To Get List Reduzieren Arithmetischer Überlauf zu werfen

[1..100000] |> Seq.sum 

bekomme ich folgende Fehlermeldung:

System.OverflowException: Arithmetic operation resulted in an overflow. 
    at <StartupCode$FSI_0003>[email protected]() 
Stopped due to error 

Allerdings, wenn ich tun:

[1..100000] |> List.reduce (+) 

ich:

val it : int = 705082704 

ich zwar erkennen, Diese beiden Teile des Codes sollten das gleiche p erreichen Sie sind sehr unterschiedlich. Ich bin nur neugierig, gibt es eine Möglichkeit, die List.reduce die OverflowException zu werfen, anstatt mir eine schlechte Antwort zu geben?

+1

Nur eine Ergänzung zu bestehenden Antworten: Summe von '1..100000 = (100001 * 100000)/2 = 50000 50000 = 0x12A06B550' was ein Überlauf ist. Löschen eines Überlauf-Bits: '0x12A06B550 - 0x100000000 = 0x2A06B550 = 705082704'. – bytebuster

Antwort

7

Sie können ein getestetes Operator verwenden.

[1..100000] |> List.reduce (Checked.(+)) 
7

Von der f # Quellcode

[<CompiledName("Sum")>] 
let inline sum (source: seq< (^a) >) : ^a = 
    use e = source.GetEnumerator() 
    let mutable acc = LanguagePrimitives.GenericZero< (^a) > 
    while e.MoveNext() do 
     acc <- Checked.(+) acc e.Current 
    acc 

Beachten Sie die Markiert (Operator) diese Kontrollen für die Arithmetik überläuft ...

http://msdn.microsoft.com/en-us/library/vstudio/ee340296.aspx