2

特定の制限を下回るすべての素数を見つけるアルゴリズムを実装しようとしています。ただし、制限に達すると、46350突然out of rangeエラー メッセージが表示されます。

panic: runtime error: index out of range

goroutine 1 [running]:
main.main()
    /tmpfs/gosandbox-433...fd004/prog.go:16 +0x1a8

ここで何が間違っているかを指摘する助けがあれば幸いです(そして、この魔法の数字46350はどこから来たのですか?)。

再現するには、次のコードをGoogle サンドボックスにドロップしてコメントを外しlimit++ます (またはこのリンクを使用します)。

package main

func main() {
    limit := 46349
    //limit++
    sieved_numbers := make([]bool, limit)
    var j = 0
    var i = 2

    for ; i < limit; i++ {
        if !sieved_numbers[i] {
            for j = i * i; j < limit;j += i {
                sieved_numbers[j] = true
            }
        }
    }
}
4

3 に答える 3

9

wheni == 46349j = i * iオーバーフローし、負の数が残るからです。ループ条件は依然として true ですが、配列の境界の外側にあるため、パニックが発生します。

ネストされたループの最初のステートメントとしてa を追加し、fmt.Println(i, j)それをローカル マシンで実行すると (サンドボックスでタイムアウトになります)、それが発生することがわかります。

于 2013-04-04T21:38:40.987 に答える
4

i*i = 2148229801いつi==463492^31符号付き 32 ビット整数は、負になる前に ~ (32 ビット - 符号の 1 ビット) にしか到達できません。具体的には、変数は の値をとり(2^32)/2 - (46349^2)ます-746153

この計算を実行したい場合は、unsigned int または int64 を使用してみてください。

package main

// import "fmt"

func main() {
    var limit uint
    limit = 46349
    limit++
    sieved_numbers := make([]bool, limit)
    var j uint = 0
    var i uint = 2

    for ; i < limit; i++ {
        if !sieved_numbers[i] {
            for j = i * i; j < limit; j += i {
                sieved_numbers[j] = true
            }
        }
    }
}

遊び場で試してみてください

于 2013-04-04T21:48:43.343 に答える
2

i * i32 ビット符号付き整数の最大サイズより大きい数値を生成します。

にはより大きなデータ型を使用する必要がありますj

ウィキペディアで整数について読む

于 2013-04-04T21:39:35.930 に答える