2013-08-20 9 views
7

Così, ieri mentre si lavorava attraverso un codice F # come parte di un esercizio di codifica, un altro sviluppatore ha sottolineato qualcosa di interessante. Stavamo solo facendo una rapida porzione di codice per dimostrare di sommare una lista. Se faccio:Come ottenere la lista Ridurre il trabocco aritmetico

[1..100000] |> Seq.sum 

ottengo il seguente errore:

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

Tuttavia, se faccio:

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

ottengo:

val it : int = 705082704 

mi rendo conto, anche se questi due pezzi di codice dovrebbero realizzare lo stesso p Scopo sono molto diversi. Sono solo curioso c'è un modo per ottenere il List.reduce di lanciare l'OverflowException piuttosto che darmi una cattiva risposta?

+1

Solo un'aggiunta alle risposte esistenti: somma di '1..100000 = (100001 * 100000)/2 = 50000 50000 = 0x12A06B550' che è un overflow. Eliminazione di un bit di overflow: '0x12A06B550 - 0x100000000 = 0x2A06B550 = 705082704'. – bytebuster

risposta

7

È possibile utilizzare un operatore controllato:.

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

Dal codice F # source

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

Avviso del Controllato (operatore) questo i controlli per l'aritmetica overflow ...

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

Problemi correlati