猿问

Go中的索引突然超出范围

我正在尝试实现一种算法来查找低于某个限制的所有素数。但是,当达到限制时,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 沙箱并取消注释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

            }

        }

    }

}


鸿蒙传说
浏览 288回答 3
3回答

MM们

因为 when&nbsp;i == 46349,j = i * i溢出,你留下一个负数。循环条件仍然为真,但它超出了数组的边界,因此您会感到恐慌。添加 afmt.Println(i, j)作为嵌套循环中的第一条语句,并在本地机器上运行它(它会在沙箱上超时),你会看到它发生。

蝴蝶不菲

i*i = 2148229801当i==46349. 有符号的 32 位整数2^31在变为负数之前只能达到 ~ (32 位 - 1 位符号)。具体来说,您的变量将采用(2^32)/2 - (46349^2)which is的值-746153。如果您想执行此计算,请尝试使用 unsigned int 或 int64。package main// import "fmt"func main() {&nbsp; &nbsp; var limit uint&nbsp; &nbsp; limit = 46349&nbsp; &nbsp; limit++&nbsp; &nbsp; sieved_numbers := make([]bool, limit)&nbsp; &nbsp; var j uint = 0&nbsp; &nbsp; var i uint = 2&nbsp; &nbsp; for ; i < limit; i++ {&nbsp; &nbsp; &nbsp; &nbsp; if !sieved_numbers[i] {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for j = i * i; j < limit; j += i {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sieved_numbers[j] = true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

慕田峪4524236

i * i&nbsp;产生一个大于 32 位有符号整数的最大大小的数字。您应该为 使用更大的数据类型j。阅读维基百科上的整数
随时随地看视频慕课网APP

相关分类

Go
我要回答