簡體   English   中英

f#對一個Int32引發的列表求和算術運算導致溢出

[英]f# sum a List of Int32 throws Arithmetic operation resulted in an overflow

我正在嘗試將所有質數的總和從0到2000000

這是我的代碼:

let getPrimesUpTo (x : System.Int32) =
    let upperBound = Convert.ToInt32(Math.Sqrt(Convert.ToDouble(x)))

    let allNumbers = ref [1..x] in    
    for div = 2 to upperBound do allNumbers := List.filter (fun num -> (num % div <> 0 || div >= num)) !allNumbers    
    allNumbers

let sop = 
    let nums = !(getPrimesUpTo 2000000)
    List.sum nums

當我運行它時,我得到:“算術運算導致溢出”

如果我不執行List.sum,我會得到素數列表

大概List.sum將嘗試將這些值求和為Int32值...並且可能最多2,000,000的質數之和大於Int32.MaxValue 我懷疑Int64會好起來-因此,請嘗試僅將Convert.ToInt32更改為Convert.ToInt64

List.sum使用檢查的運算符,它們會引發溢出。 您可以通過源代碼追蹤

List.sum calls Seq.sum
Seq.sum calls Checked.(+)

Checked.(+)在溢出時引發錯誤。 旁注:這就是為什么List.Fold (+)List.sum更快的List.sum

要解決此問題,您需要將代碼更改為使用64位int(應該足夠大),我還整理了double和int之間的轉換

let getPrimesUpTo (x : int64) =
    let upperBound = x |> float |>sqrt |> int64

    let allNumbers = ref [1L..x]    
    for div in 2L..upperBound do allNumbers := List.filter (fun num -> (num % div <> 0L || div >= num)) !allNumbers    
    allNumbers

let sop = 
    let nums = !(getPrimesUpTo 2000000L)
    List.sum nums

這種計算素數的方法效率很低。 我已經編寫了一些相當不錯的代碼來計算F#中的大量素數-參見此處https://stackoverflow.com/a/8371684/124259

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM