我正在尝试将所有素数的总和从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,我会得到素数列表
答案 0 :(得分:3)
据推测,List.sum
将尝试将值加总为Int32
值...并且可能是2,000,000的素数之和大于Int32.MaxValue
。我怀疑Int64
会好起来 - 所以请尝试将Convert.ToInt32
更改为Convert.ToInt64
。
答案 1 :(得分: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