1

我试图得到从 0 到 2 000 000 的所有素数的总和

这是我的代码:

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 我会得到素数列表

4

2 回答 2

3

大概List.sum是要尝试将这些值求和为一个Int32值......并且大概到 2,000,000 的素数之和大于Int32.MaxValue. 我怀疑Int64会没问题 - 所以试着Convert.ToInt32改成Convert.ToInt64.

于 2012-05-24T10:19:27.790 回答
2

List.sum使用引发溢出的检查运算符。你可以通过源来追逐这个

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

Checked.(+)溢出时抛出错误。旁注:这就是为什么List.Fold (+)List.sum

要解决此问题,您需要更改代码以使用 64 位整数(应该足够大),我还整理了 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

于 2012-05-24T10:47:10.507 回答