1

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を実行しないと、素数のリストが表示されます

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 に答える