Home >Backend Development >Golang >Golang uses Exp for big.Int in structure strangely changes value
Below, a
has undergone an unexpected change. d
is constructed using the value of a
(*a
), then d.c
is changed correctly. But why is a
changed to the first parameter of 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]}}
I hope a
remains the same.
Edit: To add, I also printed the pointer addresses of a
, b
, d.c
, d.q
, and in Exp
Different before and after: fmt.Printf("%p %p %p %p \n", &a, &b, &d.c, &d.q)
Here is a simpler example showing the same content:
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
The first thing to consider is y.Exp
"Set z = x**y mod |m|
(i.e. m
sign is ignored), and z is returned.";Therefore the value of y
changes (as shown above).
To understand why the value of x
is changed, you can start with the Documentation:
"Shallow copy" is exactly what y := *x
above (or d := Decimal{*a, *b}
in code) does. So the solution is to follow the advice above:
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
(You can do something similar in the example).
To explain why this happens, you need to see big.Int
is defined. This requires checking some documentation, but it boils down to (simplified!):
type Int struct { neg bool // sign abs []uint // absolute value of the integer }
Therefore, making a shallow copy of it will cause the slices of both instances to share the same backing array (this may lead to unpredictable results when elements in the slice change).
In your example, when set
has been run. An easier way to demonstrate this is:
x := big.NewInt(1) y := *x y.Set(big.NewInt(11)) fmt.Println(x) // 11 fmt.Println(&y) // 11
The above is the detailed content of Golang uses Exp for big.Int in structure strangely changes value. For more information, please follow other related articles on the PHP Chinese website!