Go语言big.Int切片append后元素重复问题求助
问题排查与修复方案
嘿,这个问题我之前也碰到过!核心原因是big.Int属于引用类型,你往切片里加的其实都是同一个n的指针。每次循环里n.Add(n, big.NewInt(2))修改的是同一个对象的内容,所以切片里的所有元素最终都会指向最后一次修改后的n(也就是11),这就导致输出全是11了。
另外你的循环条件也和预期不符:101的整数平方根是10(因为10²=100≤101,11²=121>101),原来的n.Cmp(squareRoot) == -1(也就是n < 10)会让循环在n=9之后就停止,根本不会处理到11。如果你的目标是包含11,得先调整范围判断的逻辑。
修正后的代码(符合你的预期输出)
import ( "fmt" "math/big" ) func main() { i := big.NewInt(101) var divisorsOfPrime []*big.Int squareRoot := big.NewInt(0).Sqrt(i) // 计算平方根的向上取整:如果平方根的平方不等于原数,就加1 squaredRoot := big.NewInt(0).Mul(squareRoot, squareRoot) if squaredRoot.Cmp(i) != 0 { squareRoot.Add(squareRoot, big.NewInt(1)) } for n := big.NewInt(3); n.Cmp(squareRoot) <= 0; n.Add(n, big.NewInt(2)) { // 关键:创建n的副本加入切片,避免所有元素引用同一个对象 divisorsOfPrime = append(divisorsOfPrime, big.NewInt(0).Set(n)) } fmt.Println(divisorsOfPrime) }
两个关键改动点
- 解决引用类型的坑:每次向切片添加元素时,用
big.NewInt(0).Set(n)创建一个全新的big.Int对象,并复制当前n的值。这样切片里的每个元素都是独立的,后续修改n不会影响已经加入切片的元素。 - 调整范围判断:先计算平方根的向上取整值(101的平方根约10.049,向上取整是11),然后循环条件改为
n <= 向上取整后的平方根,这样就能包含11了。
运行这段代码,就能得到你期望的[3 5 7 9 11]啦!
内容的提问来源于stack exchange,提问作者ungless
相关产品推荐
相关产品推荐

