2013-08-20 7 views
7

昨日、コーディング演習の一部としてF#コードを使用している間に、別の開発者が興味深いことを指摘しました。リストを集計する方法を示すために、簡単なコードを実行していました。私が行う場合:私がしなければ、しかしリストを取得して算術オーバーフローを減らす方法

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

[1..100000] |> Seq.sum 

を私は次のエラーを取得する

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

は私が手:

val it : int = 705082704 

私はものの実現しますこれらの2つのコードは、同じp彼らは非常に異なっていると言います。私はちょうど興味がありますが、私に悪い答えを与えるよりも、OverflowExceptionをスローするList.reduceを取得する方法はありますか?

+1

既存の回答に加えて、「1..100000 =(100001 * 100000)/ 2 = 50000」の合計50000 = 0x12A06B550」となる。オーバーフロービットを破棄する: '0x12A06B550 - 0x100000000 = 0x2A06B550 = 705082704'。 – bytebuster

答えて

7

あなたがチェック演算子を使用することができます。F#ソースコード

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

お知らせチェック(オペレータ)算術演算のために、このチェックがオーバーフローするから

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