首頁 > 後端開發 > Golang > 主體

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

王林
發布: 2024-02-12 14:00:07
轉載
857 人瀏覽過

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
}
登入後複製

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

在您的範例中,當 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
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!