在實際開發中,對於超出 int64 或者 uint64 類型的大數進行計算時,如果對精度沒有要求,使用 float32 或者float64 就OK,但如果對精度有嚴格要求的時候,浮點數就不可用了,因為浮點數在內存中只能被近似的表示。
Go語言中 math/big 包實現了大數字的多精度計算,支持 Int(有符號整數)、Rat(有理數)和 Float(浮點數)等數字類型。這些類型可以實現任意位數的數字,只要內存足夠大,但缺點是需要更大的內存和處理開銷,這使得它們使用起來要比內置的數字類型慢很多。
為實現區塊鏈的搭建,用big.Int進行哈希值的計算再合適不過。
下面是包括big.Int聲明,比較大小,移位和與其他類型轉換的例子:
package main
import (
"fmt"
"math/big"
)
func main() {
//可以不聲明,直接傳入NewInt
var v1 int64
var v2 int64
v1 = 10086
v2 = 100086
//創建Int類型,NewInt 只能由 int64 ——> big.Int
a := big.NewInt(v1)
b := big.NewInt(v2)
//比較a和b的大小
//a<b返回-1,a>b返回1,a=b返回0
isValid1 := a.Cmp(b)
//返回bool類型
isValid2 := a.Cmp(b) == 1
isValid3 := a.Cmp(b) == -1
fmt.Println(isValid1)
fmt.Println(isValid2)
fmt.Println(isValid3)
//定義Int
c := big.NewInt(1)
//將a向左移動20位
c.Lsh(c, uint(20))
//10進制
fmt.Printf("將a向左移動20位后為(10進制):%d\n", c)
//16進制
fmt.Printf("將a向左移動20位后為(16進制):%x\n", c)
//將byte數組類型轉換為big.Int類型
v3 := []byte{4,5}
hashInt := new(big.Int)
hashInt.SetBytes(v3[:])
fmt.Println(v3)
fmt.Println(hashInt)
//同理:
//string -> big.Int : s.SetString
//big.Int > string : b.String()
//...
}