Go中的指数突然超出范围

时间:2013-04-04 21:30:22

标签: go

我正在尝试实施algorithm to find all primes below a certain limit。但是,当限制达到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来自哪里?)。

要重现,请将以下代码放入googles sandbox并取消注释limit++(或使用this link):

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
            }
        }
    }
}

3 个答案:

答案 0 :(得分:9)

因为当i == 46349时,j = i * i溢出并且您留下负数。循环条件仍然是正确的,但它超出了数组的边界,所以你会感到恐慌。

在嵌套循环中添加fmt.Println(i, j)作为第一个语句,然后在本地计算机上运行它(它会在沙箱上超时),你会看到它发生。

答案 1 :(得分:4)

i*i = 2148229801时{p> i==46349。有符号的32位整数在变为负数之前只能达到〜2^31(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
            }
        }
    }
}

Try it on the playground

答案 2 :(得分:2)

i * i生成的数字大于32位有符号整数的最大值。

您应该为j使用更大的数据类型。

了解Wikipedia

上的整数