golang

[golang]暗号通貨の計算する時に気をつけたい事

ethereumとかで今の残高に0.000000000000000001ETH足したらいくらになるよ。みたいな計算の時の話。

普通に小数だしfloat64だろ〜って感じで

current := 0.123456789012345678
price   := 0.000000000000000001
total := current + price

とかやると、結果は

0.12345678901234568

となる。本当は

0.123456789012345679

になってほしいのに…。

これは、golangのfloat64がIEEE754に準拠しているために起こる丸め誤差である。

https://golang.org/ref/spec#Numeric_types

このような大きな桁数の計算を行う場合、golangにはbigというモジュールが存在する。

bigにはbig.Floatとbig.Intがあるが、ここではgethの実装に習いbig.Intを使って計算する。(つまり単位weiで計算する)

current := big.NewInt(123456789012345678)
price := big.NewInt(1)
total := new(big.Int).Add(current, price)
fmt.Print(total)

結果は

123456789012345679 // = 0.123456789012345679ETH

となった。