首頁 >後端開發 >Golang >Golang 在結構體中使用 Exp for big.Int 奇怪地改變了值

Golang 在結構體中使用 Exp for big.Int 奇怪地改變了值

王林
王林轉載
2024-02-12 14:00:07913瀏覽

Golang 在结构体中使用 Exp for big.Int 奇怪地改变了值

問題內容

在下面,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]}}

我希望 a 保持不變。

編輯:要新增的是,我還列印了abd.cd.q 的指標位址,並且在Exp 之前和之後都不同: fmt.Printf("%p %p %p %p \n", &a, &b, &d.c, &d.q)

解決方法

這是一個更簡單的範例,顯示了相同的內容:

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

首先要考慮的是y.Exp 「設定z = x**y mod |m| (即m的符號被忽略),並傳回z。";因此y 的值發生變化(如上所示)。

要了解為什麼會改變 x 的值,可以從文件開始:

「淺複製」正是上面的 y := *x (或程式碼中的 d := Decimal{*a, *b} )所做的。所以解決方案是遵循上面的建議:

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

(您可以在範例中執行類似的操作)。

要解釋為什麼會發生這種情況,您需要查看big.Int 已定義。這需要檢查一些文件,但歸結為(簡化!):

type Int struct {
    neg bool // sign
    abs []uint // absolute value of the integer
}

因此,對其進行淺複製將導致兩個實例的切片共享相同的後備數組 (當切片中的元素發生更改時,這可能會導致不可預測的結果)。

在您的範例中,當 set 已執行。展示這一點的更簡單方法是:

x := big.NewInt(1)
y := *x
y.Set(big.NewInt(11))
fmt.Println(x)  // 11
fmt.Println(&y) // 11

以上是Golang 在結構體中使用 Exp for big.Int 奇怪地改變了值的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除