英文:
Index suddenly out of range in Go
问题
我正在尝试实现一个找出小于某个限制的所有质数的算法。然而,当限制达到46350
时,我突然收到一个“超出范围”的错误信息:
panic: runtime error: index out of range
goroutine 1 [running]:
main.main()
/tmpfs/gosandbox-433...fd004/prog.go:16 +0x1a8
如果有人能帮我指出这里出了什么问题,我将不胜感激(而这个神奇的数字46350
是从哪里来的?)。
要重现此问题,请将以下代码放入谷歌沙箱并取消注释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
}
}
}
}
英文:
I am trying to implement an algorithm to find all primes below a certain limit. However, when the limit reaches 46350
i suddenly get an out of range
error message:
panic: runtime error: index out of range
goroutine 1 [running]:
main.main()
/tmpfs/gosandbox-433...fd004/prog.go:16 +0x1a8
Any help to point me to what is wrong here is appreciated (and were does this magic number 46350
come from?).
To reproduce drop the following code into googles sandbox and uncomment limit++
(or use 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
}
}
}
}
答案1
得分: 9
因为当 i == 46349
时,j = i * i
溢出,导致得到一个负数。循环条件仍然为真,但它超出了数组的边界,所以会出现 panic。
在嵌套循环的第一条语句中添加 fmt.Println(i, j)
,并在本地机器上运行它(在沙盒中会超时),你会看到这种情况发生。
英文:
Because when i == 46349
, j = i * i
overflows and you're left with a negative number. The loop condition is still true, but it's outside the boundaries of the array, so you get a panic.
Add a fmt.Println(i, j)
as the first statement in your nested loop, and run it on your local machine (it'll time out on the sandbox) and you'll see it happen.
答案2
得分: 4
i*i = 2148229801
当 i==46349
。一个有符号的32位整数在变为负数之前只能达到约 2^31
(32位 - 1位用于表示符号)。具体来说,你的变量将会取值为 (2^32)/2 - (46349^2)
,即 -746153
。
如果你想执行这个计算,可以尝试使用无符号整数或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
}
}
}
}
英文:
i*i = 2148229801
when i==46349
. A signed 32 bit integer can only reach ~2^31
(32 bits - 1 bit for the sign) before it becomes negative. Specifically, your variable would have taken on the value of (2^32)/2 - (46349^2)
which is -746153
.
If you'd like to perform this computation, try using an unsigned int or an 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
}
}
}
}
答案3
得分: 2
i * i
产生的数字大于32位有符号整数的最大值。
你应该为j
使用一个更大的数据类型。
在Wikipedia上阅读关于整数的内容。
英文:
i * i
produces a number which is greater than the maxiumum size of a 32 bit signed integer.
You should use a larger data type for j
.
Read about integers on Wikipedia
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论