Golang中数组Z[64]的值为什么仍然是0/1
Golang中数组Z[64]的值为什么仍然是0/1
// task1 project main.go
package main
import (
"fmt"
"math/big"
//"os"
//"strconv"
)
//var b [64]big.Rat
func GFS(z [64]big.Rat, c big.Rat, y [6]uint, w [6]uint, count uint) {
var temp big.Rat
switch count {
case 0:
if y[0] == 1 && y[1] == 1 {
temp.Mul(&c, big.NewRat(14, 15))
w[1] = 1
GFS(z, temp, y, w, 1+count)
temp.Mul(&c, big.NewRat(1, 15))
w[1] = 0
GFS(z, temp, y, w, 1+count)
} else {
w[1] = y[1]
GFS(z, c, y, w, 1+count)
}
case 1:
if y[2] == 1 && y[3] == 1 {
temp.Mul(&c, big.NewRat(14, 15))
w[3] = 1
GFS(z, temp, y, w, 1+count)
temp.Mul(&c, big.NewRat(1, 15))
w[3] = 0
GFS(z, temp, y, w, 1+count)
} else {
w[3] = y[3]
GFS(z, c, y, w, 1+count)
}
case 2:
if y[4] == 1 && y[5] == 1 {
temp.Mul(&c, big.NewRat(14, 15))
w[5] = 1
GFS(z, temp, y, w, 1+count)
temp.Mul(&c, big.NewRat(1, 15))
w[5] = 0
GFS(z, temp, y, w, 1+count)
} else {
w[5] = y[5]
GFS(z, c, y, w, 1+count)
}
case 3:
var m uint
for i := uint(0); i < 6; i++ {
m += w[i] << i
}
//fmt.Printf(z[m].String())
temp.Mul(&c, big.NewRat(1, 63))
z[m].Add(&z[m], &temp)
default:
break
}
}
func main() {
var z [64]big.Rat
var y [6]uint
var w [6]uint
var c = *big.NewRat(1, 1)
for i := 1; i < 64; i++ {
z[i] = *big.NewRat(0, 1)
}
for i := uint(1); i < 64; i++ {
y[0] = i & 0x1
y[1] = i & 0x2 >> 1
y[2] = i & 0x4 >> 2
y[3] = i & 0x8 >> 3
y[4] = i & 0x10 >> 4
y[5] = i & 0x20 >> 5
w[0] = y[0]
w[2] = y[2]
w[4] = y[4]
GFS(z, c, y, w, 0)
//fmt.Println(y)
}
for i := 0; i < 64; i++ {
fmt.Printf(z[i].String())
fmt.Println()
}
}
为什么数组 Z[64] 的值仍然是 0/1

更多关于Golang中数组Z[64]的值为什么仍然是0/1的实战教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言(以及其他编程语言中)中,数组的索引从0开始。因此,如果你声明一个数组 a[64] int,你将得到一个包含0到63个元素的数组。
在您的代码中,数组 z [64]big.Rat 的值保持为 0/1 的原因是由于 big.Rat 类型的初始化和在递归函数 GFS 中传递数组的方式导致的。以下是关键问题分析:
-
数组传递方式:在 Go 中,数组是值传递的。当您将数组
z传递给GFS函数时,函数接收的是数组的副本,而不是原始数组的引用。因此,在GFS函数中对z的任何修改(例如z[m].Add(&z[m], &temp))都只影响副本,不会改变main函数中的原始数组z。这导致所有计算后的值无法反映到原始数组中,因此z保持初始的0/1值。 -
初始化问题:在
main函数中,您通过循环将z的元素初始化为0/1(即big.NewRat(0, 1))。由于上述传递问题,这些初始值从未被更新。 -
递归调用中的数组副本:每次递归调用
GFS时,都会传递数组z的新副本,修改仅作用于当前副本,最终丢失。
为了修复这个问题,您应该使用切片(slice)或指针来传递数组,以确保修改在原始数组上生效。以下是修改后的代码示例,使用切片来避免值传递问题:
package main
import (
"fmt"
"math/big"
)
// 修改 GFS 函数以接收切片而不是数组
func GFS(z []big.Rat, c big.Rat, y [6]uint, w [6]uint, count uint) {
var temp big.Rat
switch count {
case 0:
if y[0] == 1 && y[1] == 1 {
temp.Mul(&c, big.NewRat(14, 15))
w[1] = 1
GFS(z, temp, y, w, 1+count)
temp.Mul(&c, big.NewRat(1, 15))
w[1] = 0
GFS(z, temp, y, w, 1+count)
} else {
w[1] = y[1]
GFS(z, c, y, w, 1+count)
}
case 1:
if y[2] == 1 && y[3] == 1 {
temp.Mul(&c, big.NewRat(14, 15))
w[3] = 1
GFS(z, temp, y, w, 1+count)
temp.Mul(&c, big.NewRat(1, 15))
w[3] = 0
GFS(z, temp, y, w, 1+count)
} else {
w[3] = y[3]
GFS(z, c, y, w, 1+count)
}
case 2:
if y[4] == 1 && y[5] == 1 {
temp.Mul(&c, big.NewRat(14, 15))
w[5] = 1
GFS(z, temp, y, w, 1+count)
temp.Mul(&c, big.NewRat(1, 15))
w[5] = 0
GFS(z, temp, y, w, 1+count)
} else {
w[5] = y[5]
GFS(z, c, y, w, 1+count)
}
case 3:
var m uint
for i := uint(0); i < 6; i++ {
m += w[i] << i
}
temp.Mul(&c, big.NewRat(1, 63))
z[m].Add(&z[m], &temp) // 现在修改会作用于原始切片
default:
break
}
}
func main() {
z := make([]big.Rat, 64) // 使用切片代替数组
var y [6]uint
var w [6]uint
c := *big.NewRat(1, 1)
// 初始化切片元素为 0/1
for i := range z {
z[i] = *big.NewRat(0, 1)
}
for i := uint(1); i < 64; i++ {
y[0] = i & 0x1
y[1] = i & 0x2 >> 1
y[2] = i & 0x4 >> 2
y[3] = i & 0x8 >> 3
y[4] = i & 0x10 >> 4
y[5] = i & 0x20 >> 5
w[0] = y[0]
w[2] = y[2]
w[4] = y[4]
GFS(z, c, y, w, 0) // 传递切片,修改会持久化
}
for i := 0; i < 64; i++ {
fmt.Printf(z[i].String())
fmt.Println()
}
}
在这个修改版本中:
- 我们将
z从数组[64]big.Rat改为切片[]big.Rat,并使用make初始化。 GFS函数现在接收一个切片参数,切片在 Go 中是引用类型,传递时不会复制底层数组,因此对z[m]的修改会直接影响main函数中的原始数据。- 其他逻辑保持不变,但现在
z的值会在递归过程中正确更新,不再保持为0/1。
运行此代码后,z 数组的值将根据递归计算更新,显示非零分数结果。

