2013-08-20 16 views
7

Yani, bir kodlama alıştırmasının parçası olarak bazı F # kodları üzerinde çalışırken, başka bir geliştirici ilginç bir şey işaret etti. Bir listeyi toplamak için sadece hızlı bir kod parçası yapıyorduk. Ben yaparsanız: eğer yaparsam, AncakListe Nasıl Aritmetik Taşma Atmak İçin Azaltılır

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

:

[1..100000] |> Seq.sum 

aşağıdaki hatayı alıyorum

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

alıyorum:

val it : int = 705082704 

Ben her ne kadar fark Bu iki kod parçası aynı payı gerçekleştirmelidir çok farklı olduklarını düşünün. Ben sadece meraklı bir cevap vermek yerine OverflowException atmak için List.reduce almak için bir yol var mı merak ediyorum?

+1

Sadece mevcut cevaplara ek olarak: '1..100000 = (100001 * 100000)/2 = 50000 50000 = bir taşma olan 0x12A06B550'. Bir taşma biti bırakılıyor: '0x12A06B550 - 0x100000000 = 0x2A06B550 = 705082704'. – bytebuster

cevap

7

Bir kontrol operatörünü kullanabilirsiniz. F # kaynak kodu

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

Bildirim İşaretli (operatör) aritmetik için bu kontroller taşıyor itibaren

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