亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Golang 中使用 big.Int 進行加法/乘法?

如何在 Golang 中使用 big.Int 進行加法/乘法?

Go
Cats萌萌 2022-07-11 15:40:11
我正在嘗試編寫一個返回斐波那契數列的第 n 個數字的函數。從返回 int 到 big.Int 時,我遇到了麻煩。這是普通版本,它只是使用矩陣求冪來找到斐波那契數列的第 n 個數。它工作得很好并返回我想要的值:func normalFib(n int) int {    if n == 0 || n == 1 {        return n    }    n -= 2    a, b, c := 1, 1, 0    x, y := 1, 1    var evenNum [3]int    var oddNum [2]int    for n > 0 {        if n%2 == 0 {            temp := []int{a*a + b*b, a*b + b*c, b*b + c*c}            a, b, c = temp[0], temp[1], temp[2]            copy(evenNum[:], temp)            n /= 2        } else {            temp := []int{x*a + y*b, x*b + y*c}            x, y = temp[0], temp[1]            copy(oddNum[:], temp)            n--        }    }    return oddNum[0]}func main() {    fmt.Println(normalFib(10)) // Outputs 55}上述函數的中間值如下所示:The value of N is currently: 8 The values of a, b, c: 2 1 1   The value of N is currently: 4 The values of a, b, c: 5 3 2   The value of N is currently: 2 The values of a, b, c: 34 21 13The value of N is currently: 1 The values of x, y: 55 34      // x is correct!這是 big.Int 版本。由于 big.Add() 和 big.Mul() 函數的工作方式,我嘗試使用它創建三個結果變量 d、e 和 f,它們將為臨時數組中的每個值臨時存儲這些函數的結果。將 a、b、c 的值設置為切片的值(如果是奇數,則設置為 x、y)將臨時切片復制到其各自的數組(evenNum 或oddNum)。
查看完整描述

1 回答

?
倚天杖

TA貢獻1828條經驗 獲得超3個贊

正如類型名稱所暗示的那樣, a*big.Int是一個指針,并且根據文檔big.Int.Add:


將集合 z 添加到總和 x+y 并返回 z。


“回報z”很重要,因為這意味著當你這樣做時:


temp := []*big.Int{

    d.Add(e.Mul(a, a), f.Mul(b, b)),

    d.Add(e.Mul(a, b), f.Mul(b, c)),

    d.Add(e.Mul(b, b), f.Mul(c, c))

}

切片的所有三個元素最終都是指向相同的指針big.Int,即指向d. Add您的三個調用中的每一個都可能會更改d,但它們都在更改(并返回指向)相同的單個對象,這不是您想要的。


為了避免這種行為,您需要為每個不同的結果創建一個新的、不同的對象,例如:


temp := []*big.Int{

    big.NewInt(0).Add(big.NewInt(0).Mul(a, a), big.NewInt(0).Mul(b, b)),

    big.NewInt(0).Add(big.NewInt(0).Mul(a, b), big.NewInt(0).Mul(b, c)),

    big.NewInt(0).Add(big.NewInt(0).Mul(b, b), big.NewInt(0).Mul(c, c)),

 }

如果你想最小化分配,你應該能夠做到:


x, y := big.NewInt(0), big.NewInt(0)

temp := []*big.Int{

    big.NewInt(0).Add(x.Mul(a, a), y.Mul(b, b)),

    big.NewInt(0).Add(x.Mul(a, b), y.Mul(b, c)),

    big.NewInt(0).Add(x.Mul(b, b), y.Mul(c, c)),

}

因為Adds它們是按順序完成的并且指向和的指針x沒有y保留,所以你重用它們的副本這一事實不會引起問題。但是對于切片的三個元素,您需要不同的對象。


查看完整回答
反對 回復 2022-07-11
  • 1 回答
  • 0 關注
  • 472 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號