Goで64bitを超えるの多倍長整数を扱う方法【big.Int解説】
Go言語(golang)では、64bitを超える大きな整数を扱うためにmath/bigパッケージが用意されています。このパッケージを使うことで多倍長整数を扱えますが、少し癖があるため、始めて使う場合は難しく感じるかもしれれません。この記事では、math/big
パッケージのbit.Int
の使い方について具体例を交えながら解説します。
Go言語のmath/bigパッケージ
Go言語では、整数型では64bitを超える値を扱えることができません(だいたい、10の19乗くらい。具体的な最大値は、math.MaxInt
で定義されています。これ以上大きな値を扱う場合には、bigというパッケージを利用することになります。このパッケージを利用することで多倍長整数を扱うことができます。
パッケージを利用する場合には、以下のようにしてパッケージをインポートします。
import "math/big"
big.Intを生成する
多倍長整数を扱う場合は、big.NewInt
または、new(big.Int)
を使って初期化する必要があります。
big.NewInt
の場合は、int64の範囲の値で初期化できます。new(big.Int)
の場合は0に初期化されます。
a := big.NewInt(100)
b := new(big.Int)
文字列で値を設定
int64を超える値を代入する場合には、Set_string
を利用します。
以下のように、一度、big.Intを生成してから、設定しても良いです。SetString(s, 10)
の10は基数です。10を設定すると文字列が10進数として解釈されます。基数を指定することで、2(2進数)や16(16進数)で解釈することもできます。
n := new(big.Int)
n, _ = n.SetString(s, 10)
また、以下のようにして生成することも可能です。
c, _ := (&big.Int{}).SetString("1234567890123456789012345678901234567890", 10)
演算は関数で
big.Intを使う場合は、四則演算を含めて演算は関数を呼び出して行うことになります。
Add(足し算)
a := big.NewInt(1000)
b := big.NewInt(2000)
c := b.Add(b, a)
fmt.Println(a, b, c)
1000 3000 3000
bも3000になっている点に注意しましょう。
Sub(引き算)
a := big.NewInt(1000)
b := big.NewInt(2000)
c := b.Sub(b, a)
fmt.Println(a, b, c)
Mul(乗算)
a := big.NewInt(1000)
b := big.NewInt(2000)
c := b.Mul(b, a)
fmt.Println(a, b, c)
Div(割り算)
a := big.NewInt(1000)
b := big.NewInt(2000)
c := b.Div(b, a)
fmt.Println(a, b, c)
Mod(mod計算)
a := big.NewInt(1000)
b := big.NewInt(2000)
c := b.Mod(b, a)
fmt.Println(a, b, c)
その他
その他の演算については、こちらのサイトを確認してください。
結果を文字列に変換
結果を文字列に変換したい場合は、String()
を呼び出します。
s := c.String()
注意点(利用時にハマる点)
big.Intを使い始めた人がハマりやすい点を紹介しておきます。癖を理解すれば便利なライブラリです。
定数も含めbig.Intに変換しておく
多くの関数がbig.Intしか入力できないので、計算を行う場合は、定数を含めてbig.Intに変換しておく必要があります(一部、例外あり)。
これが結構面倒です。特に、桁数が非常に大きな値を何度も参照する場合は、変換処理を何度も行わないようにコーディングしましょう。
演算を行うと値が上書きされる
Addの部分に書きましたが、演算はc = b.Add(x, y)
の記載することができます。この時、b
の値はx+yに上書きされてしまうことに注意します。
このあたり、慣れないとバグの原因になります。
オブジェクトの再利用を考えるのであれば、演算用のbig.Intの変数を用意するのも良いかもしれません。
たとえば、calc
のような計算専用の変数を用意しておくなどです。
calc = new(big.Int)
c = calc.Add(a, b)
自分だけかもしれませんが、big.Intを使う場合に毎回ミスする部分です。a.Add(a, b)
だと、明示的にaに計算結果が代入されるイメージはないですよね
まとめ
Go言語で多倍長整数を扱う方法について説明しました。そんなに使うことはないですが、とりあえず覚えておくと良いかもしれません。