Go言語 big.Int.DivMod()徹底解説:巨大整数除算と剰余の完全ガイド
big.Int.DivMod()
とは?
big.Int.DivMod()
は、Go言語のmath/big
パッケージに用意されている関数で、非常に大きな整数(big.Int
型)の除算と剰余を同時に計算するためのものです。通常のint
型やint64
型では扱えないような、任意精度の整数を扱う際に利用されます。
関数のシグネチャ(定義)
func (z *Int) DivMod(x, y, m *Int) (*Int, *Int)
引数
m
: 計算結果である剰余が格納される*big.Int
型のポインタ。y
: 除数(割る数)となる*big.Int
型のポインタ。y
が0の場合はランタイムパニックが発生します。x
: 被除数(割られる数)となる*big.Int
型のポインタ。z
: 計算結果である商が格納される*big.Int
型のポインタ。
戻り値
(z, m)
: 計算された商と剰余が格納された*big.Int
型のポインタのペア。
動作
DivMod
は、z
にx
をy
で割った商(x div y
)を、m
に剰余(x mod y
)を設定し、そのペア(z, m)
を返します。
重要な点:ユークリッド除法
DivMod
は、Go言語の通常の/
演算子や%
演算子とは異なり、**ユークリッド除法(Euclidean division)**を実装しています。
ユークリッド除法とは、以下の関係が常に成り立つような商 q
と剰余 m
を定義するものです。
x=y×q+m
かつ、
0≤m<∣y∣ (剰余 m は常に非負で、除数 y の絶対値よりも小さい)
この定義により、x
や y
が負の数であっても、剰余が常に非負になるという特徴があります。
例
DivMod(-10, -3)
: 商4
、剰余2
(−10=(−3)×4+2)DivMod(10, -3)
: 商-3
、剰余1
(10=(−3)×(−3)+1)DivMod(-10, 3)
: 商-4
、剰余2
(−10=3×(−4)+2)DivMod(10, 3)
: 商3
、剰余1
Go言語の通常の演算子との違い
Go言語の通常の/
演算子と%
演算子は「切り捨て除算(truncated division)」に基づいています。これは、商が0方向に切り捨てられ、剰余の符号は被除数と同じになるというものです。
例(通常のGo言語の演算子)
-10 / -3 = 3
,-10 % -3 = -1
10 / -3 = -3
,10 % -3 = 1
-10 / 3 = -3
,-10 % 3 = -1
10 / 3 = 3
,10 % 3 = 1
このように、負の数の除算や剰余の計算において、big.Int.DivMod()
の挙動はGoの組み込み演算子とは異なるため、注意が必要です。ユークリッド除法が必要な場合はDivMod
を、Goの組み込み演算子と同じ挙動が必要な場合はbig.Int.QuoRem()
を使用します。
package main
import (
"fmt"
"math/big"
)
func main() {
// 例1: 正の数 ÷ 正の数
x1 := big.NewInt(10)
y1 := big.NewInt(3)
z1 := new(big.Int) // 商を格納するInt
m1 := new(big.Int) // 剰余を格納するInt
z1, m1 = z1.DivMod(x1, y1, m1)
fmt.Printf("10 div 3: 商 = %s, 剰余 = %s\n", z1.String(), m1.String()) // 出力: 商 = 3, 剰余 = 1
// 例2: 負の数 ÷ 正の数
x2 := big.NewInt(-10)
y2 := big.NewInt(3)
z2 := new(big.Int)
m2 := new(big.Int)
z2, m2 = z2.DivMod(x2, y2, m2)
fmt.Printf("-10 div 3: 商 = %s, 剰余 = %s\n", z2.String(), m2.String()) // 出力: 商 = -4, 剰余 = 2 (ユークリッド除法)
// 例3: 正の数 ÷ 負の数
x3 := big.NewInt(10)
y3 := big.NewInt(-3)
z3 := new(big.Int)
m3 := new(big.Int)
z3, m3 = z3.DivMod(x3, y3, m3)
fmt.Printf("10 div -3: 商 = %s, 剰余 = %s\n", z3.String(), m3.String()) // 出力: 商 = -3, 剰余 = 1 (ユークリッド除法)
// 例4: 負の数 ÷ 負の数
x4 := big.NewInt(-10)
y4 := big.NewInt(-3)
z4 := new(big.Int)
m4 := new(big.Int)
z4, m4 = z4.DivMod(x4, y4, m4)
fmt.Printf("-10 div -3: 商 = %s, 剰余 = %s\n", z4.String(), m4.String()) // 出力: 商 = 4, 剰余 = 2 (ユークリッド除法)
// 注意: 割り算の結果を格納するIntは、既存のIntを使用するか、new(big.Int)で新しく作成する必要があります。
// DivModはレシーバ (z) と第3引数 (m) を結果として更新し、それらを戻り値としても返します。
// このため、例えば以下のように簡略化して書くことも可能です。
quotient, remainder := new(big.Int).DivMod(big.NewInt(17), big.NewInt(5), new(big.Int))
fmt.Printf("17 div 5: 商 = %s, 剰余 = %s\n", quotient.String(), remainder.String())
}
big.Int.DivMod()
は、Goの組み込み型では扱えない大きな整数を扱う上で非常に便利な関数ですが、その特性上、いくつか注意すべき点があります。
除数 y が0の場合のパニック (runtime panic: division by zero)
エラーの状況
除数として指定するy
が0
の場合、big.Int.DivMod()
はruntime panic: division by zero
を発生させます。これは通常の整数除算と同様の挙動です。
コード例
package main
import (
"fmt"
"math/big"
)
func main() {
x := big.NewInt(100)
y := big.NewInt(0) // ゼロ除算を引き起こす
z := new(big.Int)
m := new(big.Int)
// ここでパニックが発生する
z.DivMod(x, y, m)
fmt.Printf("商: %s, 剰余: %s\n", z.String(), m.String())
}
トラブルシューティング
DivMod()
を呼び出す前に、除数y
が0でないことを確認する条件分岐を追加することが重要です。
package main
import (
"fmt"
"math/big"
)
func main() {
x := big.NewInt(100)
y := big.NewInt(0)
z := new(big.Int)
m := new(big.Int)
if y.Cmp(big.NewInt(0)) == 0 { // yが0と比較して等しい場合
fmt.Println("エラー: 除数が0です。")
return // または適切なエラーハンドリング
}
z.DivMod(x, y, m)
fmt.Printf("商: %s, 剰余: %s\n", z.String(), m.String())
}
y.Cmp(big.NewInt(0))
は、y
と0
を比較し、y
が0
と等しい場合は0
を返します。
ユークリッド除法と切り捨て除法の混同
エラーの状況
big.Int.DivMod()
はユークリッド除法を採用しているため、負の数の除算において、Goの組み込み演算子 (/
, %
) とは異なる結果を返します。この違いを理解せずにコードを書くと、期待しない結果になることがあります。
例(再掲)
Go組み込み演算子: -10 / 3 = -3
,-10 % 3 = -1
big.Int.DivMod(-10, 3)
: 商-4
、剰余2
トラブルシューティング
- Goの組み込み演算子と同じ挙動が必要な場合
big.Int.QuoRem()
を使用します。これはGoの組み込み演算子と同じ「切り捨て除算」に基づいています。 - DivModが必要な場合
剰余を常に非負にしたい、または数学的な厳密さでユークリッド除法が必要な場合はDivMod
を使用します。
package main
import (
"fmt"
"math/big"
)
func main() {
x := big.NewInt(-10)
y := big.NewInt(3)
// DivMod (ユークリッド除法)
qDivMod := new(big.Int)
rDivMod := new(big.Int)
qDivMod, rDivMod = qDivMod.DivMod(x, y, rDivMod)
fmt.Printf("DivMod(-10, 3): 商 = %s, 剰余 = %s\n", qDivMod.String(), rDivMod.String()) // 商 = -4, 剰余 = 2
// QuoRem (切り捨て除法)
qQuoRem := new(big.Int)
rQuoRem := new(big.Int)
qQuoRem, rQuoRem = qQuoRem.QuoRem(x, y, rQuoRem)
fmt.Printf("QuoRem(-10, 3): 商 = %s, 剰余 = %s\n", qQuoRem.String(), rQuoRem.String()) // 商 = -3, 剰余 = -1
// 組み込み演算子
fmt.Printf("Go組み込み: -10 / 3 = %d, -10 %% 3 = %d\n", -10/3, -10%3) // -10 / 3 = -3, -10 % 3 = -1
}
コードの意図に合わせて適切な関数を選択することが重要です。
引数のポインタ渡しと結果の再利用
エラーの状況
DivMod()
は、レシーバz
と第3引数m
に計算結果を書き込みます。これらの引数には*big.Int
型のポインタを渡す必要があります。また、引数として渡すbig.Int
インスタンスを適切に初期化しないと、ゼロ値のbig.Int
が使われたり、予期せぬ動作につながる可能性があります。
よくある誤解
- 結果を格納する
big.Int
をnew(big.Int)
で初期化せずに、単にvar z big.Int
のように宣言するだけの場合、結果が正しく書き込まれない可能性がある(ただし、これはメソッドのレシーバがポインタであるため、コンパイルエラーになることが多い)。 big.Int
のポインタではなく、値そのものを渡そうとする(コンパイルエラーになる)。
トラブルシューティング
- 既存の
big.Int
インスタンスを再利用する場合も、そのインスタンスのポインタを渡す。 new(big.Int)
を使って新しいbig.Int
インスタンスを初期化し、そのポインタを渡す。
package main
import (
"fmt"
"math/big"
)
func main() {
x := big.NewInt(25)
y := big.NewInt(7)
// 正しい使い方: new(big.Int) で初期化
quotient := new(big.Int)
remainder := new(big.Int)
// DivModはレシーバと第3引数を更新し、それらを戻り値としても返す
quotient.DivMod(x, y, remainder)
fmt.Printf("商: %s, 剰余: %s\n", quotient.String(), remainder.String())
// 戻り値を直接受け取るパターン (より一般的)
q, r := new(big.Int).DivMod(big.NewInt(25), big.NewInt(7), new(big.Int))
fmt.Printf("商: %s, 剰余: %s\n", q.String(), r.String())
// 既存の big.Int を再利用する例
a := big.NewInt(50)
b := big.NewInt(8)
// quotient と remainder を再利用
quotient.DivMod(a, b, remainder)
fmt.Printf("商: %s, 剰余: %s\n", quotient.String(), remainder.String())
}
不変性に関する誤解 (大きな問題ではないが、意識しておくべき点)
エラーの状況
big.Int
のメソッドは、多くの場合、レシーバ(メソッドを呼び出すインスタンス)を変更し、そのレシーバ自身を返します。DivMod
も同様に、商をレシーバz
に書き込み、z
を戻り値として返します。剰余は第3引数m
に書き込まれ、m
も戻り値として返されます。
これはエラーというよりは設計思想の理解の問題ですが、big.Int
の操作では、元の値を保持したい場合は明示的にコピーを作成する必要があることを意識しておくべきです。
トラブルシューティング
元のbig.Int
の値を保持したまま計算を行いたい場合は、big.Int.Set()
やbig.Int.Add()
などのメソッドを使用する前に、new(big.Int).Set(originalInt)
のようにコピーを作成します。
package main
import (
"fmt"
"math/big"
)
func main() {
originalX := big.NewInt(100)
y := big.NewInt(7)
// originalX の値を変更せずにDivModの結果を得たい場合
// 方法1: new(big.Int) を使って新しいインスタンスに結果を格納
quotient := new(big.Int)
remainder := new(big.Int)
quotient.DivMod(originalX, y, remainder) // originalX は変更されない
fmt.Printf("元のX: %s\n", originalX.String())
fmt.Printf("商: %s, 剰余: %s\n", quotient.String(), remainder.String())
// 方法2: 戻り値を直接受け取る(これがより一般的で推奨される)
// この場合も、元の引数は変更されない
q, r := new(big.Int).DivMod(originalX, y, new(big.Int))
fmt.Printf("商: %s, 剰余: %s\n", q.String(), r.String())
}
big.Int.DivMod()
を使用する際の主なポイントは以下の通りです。
- ゼロ除算の回避
除数が0にならないように常にチェックする。 - ユークリッド除法の理解
負の数の扱いがGoの組み込み演算子と異なるため、QuoRem
との違いを理解し、目的に応じて使い分ける。 - ポインタの適切な利用
引数および結果を格納するbig.Int
はポインタで渡し、必要に応じてnew(big.Int)
で初期化する。
big.Int.DivMod()
は、巨大な整数の除算と剰余を同時に計算する際に使用されます。特に、剰余が常に非負となる「ユークリッド除法」が必要な場合に役立ちます。
例1: 基本的な正の数の除算と剰余
最も基本的な使い方です。10を3で割った商と剰余を計算します。
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println("--- 例1: 基本的な正の数の除算と剰余 ---")
// 被除数 (割られる数) を10に設定
x := big.NewInt(10)
// 除数 (割る数) を3に設定
y := big.NewInt(3)
// 商と剰余を格納するための big.Int 型のポインタを初期化
// new(big.Int) は、big.Int 型のゼロ値(0)を持つ新しいインスタンスを作成し、そのポインタを返します。
quotient := new(big.Int) // 商 (quotient)
remainder := new(big.Int) // 剰余 (remainder)
// DivMod メソッドを呼び出す
// quotient.DivMod(x, y, remainder) は、x を y で割った商を quotient に、
// 剰余を remainder に格納します。
// そして、(quotient, remainder) のペアを戻り値としても返します。
quotient.DivMod(x, y, remainder)
// 結果を出力
// String() メソッドは big.Int の値を文字列として返します。
fmt.Printf("%s を %s で割ると:\n", x.String(), y.String())
fmt.Printf(" 商 = %s\n", quotient.String()) // 期待値: 3
fmt.Printf(" 剰余 = %s\n", remainder.String()) // 期待値: 1
}
解説
この例では、big.NewInt(value)
を使ってbig.Int
型のインスタンスを作成し、DivMod
に渡しています。quotient
とremainder
は計算結果が書き込まれるプレースホルダーとして機能します。
例2: 負の数の除算とユークリッド除法
big.Int.DivMod()
がユークリッド除法を実装していることを示す例です。Goの通常の/
や%
演算子とは異なる結果になる点に注目してください。
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println("\n--- 例2: 負の数の除算とユークリッド除法 ---")
testCases := []struct {
x, y int64
}{
{-10, 3}, // xが負、yが正
{10, -3}, // xが正、yが負
{-10, -3}, // xが負、yが負
}
for _, tc := range testCases {
x := big.NewInt(tc.x)
y := big.NewInt(tc.y)
qDivMod := new(big.Int)
rDivMod := new(big.Int)
qDivMod.DivMod(x, y, rDivMod)
fmt.Printf("DivMod(%s, %s):\n", x.String(), y.String())
fmt.Printf(" 商 (DivMod) = %s\n", qDivMod.String())
fmt.Printf(" 剰余 (DivMod) = %s\n", rDivMod.String())
// 参考として、Goの組み込み演算子 (`/`, `%`) の結果も表示
// big.Int.QuoRem() は組み込み演算子と同じ切り捨て除法を行う
qQuoRem := new(big.Int)
rQuoRem := new(big.Int)
qQuoRem.QuoRem(x, y, rQuoRem)
fmt.Printf(" 商 (QuoRem) = %s\n", qQuoRem.String())
fmt.Printf(" 剰余 (QuoRem) = %s\n", rQuoRem.String())
// Go組み込み型での計算 (int64に収まる範囲で)
fmt.Printf(" Go組み込み (%d / %d) = 商: %d, 剰余: %d\n\n", tc.x, tc.y, tc.x/tc.y, tc.x%tc.y)
}
}
解説
この例は、DivMod
がユークリッド除法(剰余が常に非負で、0 <= 剰余 < |除数|
)を適用することを示しています。QuoRem
関数と比較することで、その違いが明確になります。組み込みの/
や%
演算子はQuoRem
と同じ「切り捨て除算」を行います。
例3: ゼロ除算のハンドリング
DivMod
に除数として0を渡すとパニックが発生するため、事前にチェックする方法を示します。
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println("--- 例3: ゼロ除算のハンドリング ---")
x := big.NewInt(12345)
y := big.NewInt(0) // ゼロ除算を引き起こす除数
quotient := new(big.Int)
remainder := new(big.Int)
// 除数が0かどうかをチェック
// y.Cmp(big.NewInt(0)) == 0 は、yが0と等しい場合にtrueを返します。
if y.Cmp(big.NewInt(0)) == 0 {
fmt.Printf("エラー: 除数 %s がゼロです。除算できません。\n", y.String())
// ここでエラーを返す、ログに記録する、またはプログラムを終了するなどの処理を行います。
return
}
// ゼロでなければ安全に DivMod を呼び出す
quotient.DivMod(x, y, remainder)
fmt.Printf("%s を %s で割ると:\n", x.String(), y.String())
fmt.Printf(" 商 = %s\n", quotient.String())
fmt.Printf(" 剰余 = %s\n", remainder.String())
}
解説
big.Int.Cmp()
メソッドは、2つのbig.Int
の比較結果を返します。
a.Cmp(b)
が正の場合、a > b
。 この性質を利用して、除数y
が0であるかをチェックしています。a.Cmp(b)
が負の場合、a < b
。a.Cmp(b)
が0の場合、a
とb
は等しい。
例4: 戻り値を直接受け取る簡潔な書き方
DivMod
は、レシーバと第3引数を更新するだけでなく、その2つのポインタを戻り値としても返すため、より簡潔に書くことができます。
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println("\n--- 例4: 戻り値を直接受け取る簡潔な書き方 ---")
// new(big.Int).DivMod(...) のように、メソッドチェーンで記述できます。
// この場合、商と剰余を格納するための新しい big.Int インスタンスがその場で作成されます。
// 被除数と除数も一時的な big.Int インスタンスとして作成されます。
quotient, remainder := new(big.Int).DivMod(big.NewInt(100), big.NewInt(17), new(big.Int))
fmt.Printf("100 を 17 で割ると:\n")
fmt.Printf(" 商 = %s\n", quotient.String()) // 期待値: 5
fmt.Printf(" 剰余 = %s\n", remainder.String()) // 期待値: 15
// 負の数での例
qNeg, rNeg := new(big.Int).DivMod(big.NewInt(-100), big.NewInt(17), new(big.Int))
fmt.Printf("-100 を 17 で割ると(ユークリッド除法):\n")
fmt.Printf(" 商 = %s\n", qNeg.String()) // 期待値: -6
fmt.Printf(" 剰余 = %s\n", rNeg.String()) // 期待値: 2 ($-100 = 17 \times (-6) + 2$)
}
解説
この書き方は、一時的な計算結果を格納する変数名を別途宣言せずに済むため、非常に簡潔です。new(big.Int)
は新しいゼロ値のbig.Int
を作成し、そのポインタがDivMod
のレシーバおよび剰余の格納先として使用されます。
math/big
パッケージには、除算や剰余に関するいくつかのメソッドが提供されており、それぞれ異なる特性を持っています。
big.Int.QuoRem(): Goの組み込み演算子 (/, %) と同じ挙動
シグネチャ
func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int)
引数
r
: 計算結果である剰余が格納される*big.Int
型のポインタ。y
: 除数となる*big.Int
型のポインタ。y
が0の場合はランタイムパニックが発生します。x
: 被除数となる*big.Int
型のポインタ。z
: 計算結果である商が格納される*big.Int
型のポインタ。
戻り値
(z, r)
: 計算された商と剰余が格納された*big.Int
型のポインタのペア。
DivModとの使い分け
QuoRem
: Goの通常のint
型やint64
型での/
や%
と同じ結果を得たい場合。DivMod
: 剰余を常に非負にしたい、数学的なユークリッド除法が必要な場合。
コード例
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println("--- big.Int.QuoRem() の例 ---")
x := big.NewInt(-10)
y := big.NewInt(3)
// QuoRem を使用
// 商は -3、剰余は -1 (Goの組み込み演算子と同じ)
qQuoRem := new(big.Int)
rQuoRem := new(big.Int)
qQuoRem.QuoRem(x, y, rQuoRem)
fmt.Printf("QuoRem(%s, %s):\n", x.String(), y.String())
fmt.Printf(" 商 = %s\n", qQuoRem.String()) // -3
fmt.Printf(" 剰余 = %s\n", rQuoRem.String()) // -1
// 比較のための DivMod
qDivMod := new(big.Int)
rDivMod := new(big.Int)
qDivMod.DivMod(x, y, rDivMod)
fmt.Printf("DivMod(%s, %s):\n", x.String(), y.String())
fmt.Printf(" 商 = %s\n", qDivMod.String()) // -4
fmt.Printf(" 剰余 = %s\n", rDivMod.String()) // 2
}
big.Int.Quo(): 商のみを計算
シグネチャ
func (z *Int) Quo(x, y *Int) *Int
引数
y
: 除数となる*big.Int
型のポインタ。y
が0の場合はランタイムパニックが発生します。x
: 被除数となる*big.Int
型のポインタ。z
: 計算結果である商が格納される*big.Int
型のポインタ。
戻り値
z
: 計算された商が格納された*big.Int
型のポインタ。
コード例
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println("\n--- big.Int.Quo() の例 ---")
x := big.NewInt(1234567890123456789)
y := big.NewInt(98765)
quotient := new(big.Int)
quotient.Quo(x, y) // x を y で割った商を quotient に設定
fmt.Printf("%s を %s で割った商 (Quo) = %s\n", x.String(), y.String(), quotient.String())
// 負の数での例 (切り捨て除算)
xNeg := big.NewInt(-20)
yPos := big.NewInt(3)
qNeg := new(big.Int)
qNeg.Quo(xNeg, yPos)
fmt.Printf("%s を %s で割った商 (Quo) = %s\n", xNeg.String(), yPos.String(), qNeg.String()) // 期待値: -6
}
big.Int.Rem(): 剰余のみを計算
シグネチャ
func (z *Int) Rem(x, y *Int) *Int
引数
y
: 除数となる*big.Int
型のポインタ。y
が0の場合はランタイムパニックが発生します。x
: 被除数となる*big.Int
型のポインタ。z
: 計算結果である剰余が格納される*big.Int
型のポインタ。
戻り値
z
: 計算された剰余が格納された*big.Int
型のポインタ。
コード例
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println("\n--- big.Int.Rem() の例 ---")
x := big.NewInt(25)
y := big.NewInt(7)
remainder := new(big.Int)
remainder.Rem(x, y) // x を y で割った剰余を remainder に設定
fmt.Printf("%s を %s で割った剰余 (Rem) = %s\n", x.String(), y.String(), remainder.String()) // 期待値: 4
// 負の数での例 (被除数の符号に依存)
xNeg := big.NewInt(-25)
yPos := big.NewInt(7)
rNeg := new(big.Int)
rNeg.Rem(xNeg, yPos)
fmt.Printf("%s を %s で割った剰余 (Rem) = %s\n", xNeg.String(), yPos.String(), rNeg.String()) // 期待値: -4
}
big.Int.Mod(): ユークリッド剰余のみを計算
シグネチャ
func (z *Int) Mod(x, y *Int) *Int
引数
y
: 除数となる*big.Int
型のポインタ。y
が0の場合はランタイムパニックが発生します。x
: 被除数となる*big.Int
型のポインタ。z
: 計算結果である剰余が格納される*big.Int
型のポインタ。
戻り値
z
: 計算された剰余が格納された*big.Int
型のポインタ。
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println("\n--- big.Int.Mod() の例 ---")
x := big.NewInt(-25)
y := big.NewInt(7)
modulo := new(big.Int)
modulo.Mod(x, y) // x を y で割った剰余 (ユークリッド除法) を modulo に設定
fmt.Printf("%s を %s で割った剰余 (Mod) = %s\n", x.String(), y.String(), modulo.String()) // 期待値: 3 ($-25 = 7 \times (-4) + 3$)
// 比較のための Rem
remainder := new(big.Int)
remainder.Rem(x, y)
fmt.Printf("%s を %s で割った剰余 (Rem) = %s\n", x.String(), y.String(), remainder.String()) // 期待値: -4
}
メソッド | 戻り値 | 商の扱い | 剰余の符号 | 主な用途 |
---|---|---|---|---|
DivMod(x, y, m) | (商, 剰余) | ユークリッド | 非負 | 商とユークリッド剰余を同時に取得したい場合 |
QuoRem(x, y, r) | (商, 剰余) | 切り捨て | 被除数と同じ | 商とGoの組み込み演算子と同じ剰余を同時に取得 |
Quo(x, y) | 商 | 切り捨て | なし | 商のみが必要で、Goの組み込み演算子と同じ挙動でよい場合 |
Rem(x, y) | 剰余 | なし | 被除数と同じ | 剰余のみが必要で、Goの組み込み演算子と同じ挙動でよい場合 |
Mod(x, y) | 剰余 | なし | 非負 | 剰余のみが必要で、常に非負のユークリッド剰余が欲しい場合 |