Maison >développement back-end >Golang >Golang utilise Exp pour big.Int dans la structure qui change étrangement de valeur
Ci-dessous, le premier paramètre de a
发生了意外的变化。 d
使用 a
(*a
) 的值构造,然后 d.c
被正确更改。但是为什么 a
更改为 Exp
?
type Decimal struct { c big.Int // coefficient q big.Int // exponent } a := big.NewInt(1) b := big.NewInt(2) d := Decimal{*a, *b} d.c.Exp(big.NewInt(11), big.NewInt(2), big.NewInt(0)) fmt.Println(a, b, d) // 11 2 {{false [121]} {false [2]}}
J'espère que a
restera le même.
EDIT : Pour ajouter, j'ai également imprimé les adresses de pointeur de a
、b
、d.c
、d.q
的指针地址,并且在 Exp
之前和之后都不同: fmt.Printf("%p %p %p %p n", &a, &b, &d.c, &d.q)
, b
, d.c
, d.q
et dans Exp code> Différent avant et après :
fmt.Printf("%p %p %p %p n", &a, &b, &d.c, &d.q)
Voici un exemple plus simple affichant le même contenu :
x := big.NewInt(1) y := *x y.Exp(big.NewInt(11), big.NewInt(2), big.NewInt(0)) fmt.Println(x) // 11 fmt.Println(&y) // 121
La première chose à considérer est le moment où la valeur de y.Exp
“设置 z = x**y mod |m|
(即 m
的符号被忽略),并返回 z。";因此 y
change (indiqué ci-dessus).
Pour comprendre pourquoi la valeur de x
change, vous pouvez partir de la documentation :
"Copie superficielle" est exactement ce que fait y := *x
(或代码中的 d := Decimal{*a, *b}
) ci-dessus. Alors la solution est de suivre les conseils ci-dessus :
x := big.NewInt(1) y := new(big.Int).Set(x) // Avoid shallow copy y.Exp(big.NewInt(11), big.NewInt(2), big.NewInt(0)) fmt.Println(x) // 1 fmt.Println(y) // 121
(Vous pouvez faire quelque chose de similaire dans l'exemple).
Pour expliquer pourquoi cela se produit, vous devez regarder la définition de big.Int
. Cela nécessite de vérifier une certaine documentation, mais cela se résume à (simplifié !) :
type Int struct { neg bool // sign abs []uint // absolute value of the integer }
Ainsi, en faire une copie superficielle fera que les tranches des deux instances partageront le même tableau de sauvegarde (cela peut conduire à des résultats imprévisibles lorsque les éléments de la tranche changent).
Dans votre exemple, lorsque set
a été exécuté. Un moyen plus simple de le démontrer est :
x := big.NewInt(1) y := *x y.Set(big.NewInt(11)) fmt.Println(x) // 11 fmt.Println(&y) // 11
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!