我正在尝试实施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
}
}
}
}
答案 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
}
}
}
}
答案 2 :(得分:2)