Commit 841a32dd authored by Evan Shaw's avatar Evan Shaw Committed by Robert Griesemer

big: Create type nat

Changed most of the functions in nat.go to methods on nat.

R=gri
CC=golang-dev
https://golang.org/cl/976041
parent 5cd8c830
...@@ -52,7 +52,7 @@ func TestFunWW(t *testing.T) { ...@@ -52,7 +52,7 @@ func TestFunWW(t *testing.T) {
} }
func addr(x []Word) *Word { func addr(x nat) *Word {
if len(x) == 0 { if len(x) == 0 {
return nil return nil
} }
...@@ -62,26 +62,26 @@ func addr(x []Word) *Word { ...@@ -62,26 +62,26 @@ func addr(x []Word) *Word {
type funVV func(z, x, y *Word, n int) (c Word) type funVV func(z, x, y *Word, n int) (c Word)
type argVV struct { type argVV struct {
z, x, y []Word z, x, y nat
c Word c Word
} }
var sumVV = []argVV{ var sumVV = []argVV{
argVV{}, argVV{},
argVV{[]Word{0}, []Word{0}, []Word{0}, 0}, argVV{nat{0}, nat{0}, nat{0}, 0},
argVV{[]Word{1}, []Word{1}, []Word{0}, 0}, argVV{nat{1}, nat{1}, nat{0}, 0},
argVV{[]Word{0}, []Word{_M}, []Word{1}, 1}, argVV{nat{0}, nat{_M}, nat{1}, 1},
argVV{[]Word{80235}, []Word{12345}, []Word{67890}, 0}, argVV{nat{80235}, nat{12345}, nat{67890}, 0},
argVV{[]Word{_M - 1}, []Word{_M}, []Word{_M}, 1}, argVV{nat{_M - 1}, nat{_M}, nat{_M}, 1},
argVV{[]Word{0, 0, 0, 0}, []Word{_M, _M, _M, _M}, []Word{1, 0, 0, 0}, 1}, argVV{nat{0, 0, 0, 0}, nat{_M, _M, _M, _M}, nat{1, 0, 0, 0}, 1},
argVV{[]Word{0, 0, 0, _M}, []Word{_M, _M, _M, _M - 1}, []Word{1, 0, 0, 0}, 0}, argVV{nat{0, 0, 0, _M}, nat{_M, _M, _M, _M - 1}, nat{1, 0, 0, 0}, 0},
argVV{[]Word{0, 0, 0, 0}, []Word{_M, 0, _M, 0}, []Word{1, _M, 0, _M}, 1}, argVV{nat{0, 0, 0, 0}, nat{_M, 0, _M, 0}, nat{1, _M, 0, _M}, 1},
} }
func testFunVV(t *testing.T, msg string, f funVV, a argVV) { func testFunVV(t *testing.T, msg string, f funVV, a argVV) {
n := len(a.z) n := len(a.z)
z := make([]Word, n) z := make(nat, n)
c := f(addr(z), addr(a.x), addr(a.y), n) c := f(addr(z), addr(a.x), addr(a.y), n)
for i, zi := range z { for i, zi := range z {
if zi != a.z[i] { if zi != a.z[i] {
...@@ -118,39 +118,39 @@ func TestFunVV(t *testing.T) { ...@@ -118,39 +118,39 @@ func TestFunVV(t *testing.T) {
type funVW func(z, x *Word, y Word, n int) (c Word) type funVW func(z, x *Word, y Word, n int) (c Word)
type argVW struct { type argVW struct {
z, x []Word z, x nat
y Word y Word
c Word c Word
} }
var sumVW = []argVW{ var sumVW = []argVW{
argVW{}, argVW{},
argVW{[]Word{0}, []Word{0}, 0, 0}, argVW{nat{0}, nat{0}, 0, 0},
argVW{[]Word{1}, []Word{0}, 1, 0}, argVW{nat{1}, nat{0}, 1, 0},
argVW{[]Word{1}, []Word{1}, 0, 0}, argVW{nat{1}, nat{1}, 0, 0},
argVW{[]Word{0}, []Word{_M}, 1, 1}, argVW{nat{0}, nat{_M}, 1, 1},
argVW{[]Word{0, 0, 0, 0}, []Word{_M, _M, _M, _M}, 1, 1}, argVW{nat{0, 0, 0, 0}, nat{_M, _M, _M, _M}, 1, 1},
} }
var prodVW = []argVW{ var prodVW = []argVW{
argVW{}, argVW{},
argVW{[]Word{0}, []Word{0}, 0, 0}, argVW{nat{0}, nat{0}, 0, 0},
argVW{[]Word{0}, []Word{_M}, 0, 0}, argVW{nat{0}, nat{_M}, 0, 0},
argVW{[]Word{0}, []Word{0}, _M, 0}, argVW{nat{0}, nat{0}, _M, 0},
argVW{[]Word{1}, []Word{1}, 1, 0}, argVW{nat{1}, nat{1}, 1, 0},
argVW{[]Word{22793}, []Word{991}, 23, 0}, argVW{nat{22793}, nat{991}, 23, 0},
argVW{[]Word{0, 0, 0, 22793}, []Word{0, 0, 0, 991}, 23, 0}, argVW{nat{0, 0, 0, 22793}, nat{0, 0, 0, 991}, 23, 0},
argVW{[]Word{0, 0, 0, 0}, []Word{7893475, 7395495, 798547395, 68943}, 0, 0}, argVW{nat{0, 0, 0, 0}, nat{7893475, 7395495, 798547395, 68943}, 0, 0},
argVW{[]Word{0, 0, 0, 0}, []Word{0, 0, 0, 0}, 894375984, 0}, argVW{nat{0, 0, 0, 0}, nat{0, 0, 0, 0}, 894375984, 0},
argVW{[]Word{_M << 1 & _M}, []Word{_M}, 1 << 1, _M >> (_W - 1)}, argVW{nat{_M << 1 & _M}, nat{_M}, 1 << 1, _M >> (_W - 1)},
argVW{[]Word{_M << 7 & _M}, []Word{_M}, 1 << 7, _M >> (_W - 7)}, argVW{nat{_M << 7 & _M}, nat{_M}, 1 << 7, _M >> (_W - 7)},
argVW{[]Word{_M << 7 & _M, _M, _M, _M}, []Word{_M, _M, _M, _M}, 1 << 7, _M >> (_W - 7)}, argVW{nat{_M << 7 & _M, _M, _M, _M}, nat{_M, _M, _M, _M}, 1 << 7, _M >> (_W - 7)},
} }
func testFunVW(t *testing.T, msg string, f funVW, a argVW) { func testFunVW(t *testing.T, msg string, f funVW, a argVW) {
n := len(a.z) n := len(a.z)
z := make([]Word, n) z := make(nat, n)
c := f(addr(z), addr(a.x), a.y, n) c := f(addr(z), addr(a.x), a.y, n)
for i, zi := range z { for i, zi := range z {
if zi != a.z[i] { if zi != a.z[i] {
...@@ -179,41 +179,41 @@ func TestFunVW(t *testing.T) { ...@@ -179,41 +179,41 @@ func TestFunVW(t *testing.T) {
type funVWW func(z, x *Word, y, r Word, n int) (c Word) type funVWW func(z, x *Word, y, r Word, n int) (c Word)
type argVWW struct { type argVWW struct {
z, x []Word z, x nat
y, r Word y, r Word
c Word c Word
} }
var prodVWW = []argVWW{ var prodVWW = []argVWW{
argVWW{}, argVWW{},
argVWW{[]Word{0}, []Word{0}, 0, 0, 0}, argVWW{nat{0}, nat{0}, 0, 0, 0},
argVWW{[]Word{991}, []Word{0}, 0, 991, 0}, argVWW{nat{991}, nat{0}, 0, 991, 0},
argVWW{[]Word{0}, []Word{_M}, 0, 0, 0}, argVWW{nat{0}, nat{_M}, 0, 0, 0},
argVWW{[]Word{991}, []Word{_M}, 0, 991, 0}, argVWW{nat{991}, nat{_M}, 0, 991, 0},
argVWW{[]Word{0}, []Word{0}, _M, 0, 0}, argVWW{nat{0}, nat{0}, _M, 0, 0},
argVWW{[]Word{991}, []Word{0}, _M, 991, 0}, argVWW{nat{991}, nat{0}, _M, 991, 0},
argVWW{[]Word{1}, []Word{1}, 1, 0, 0}, argVWW{nat{1}, nat{1}, 1, 0, 0},
argVWW{[]Word{992}, []Word{1}, 1, 991, 0}, argVWW{nat{992}, nat{1}, 1, 991, 0},
argVWW{[]Word{22793}, []Word{991}, 23, 0, 0}, argVWW{nat{22793}, nat{991}, 23, 0, 0},
argVWW{[]Word{22800}, []Word{991}, 23, 7, 0}, argVWW{nat{22800}, nat{991}, 23, 7, 0},
argVWW{[]Word{0, 0, 0, 22793}, []Word{0, 0, 0, 991}, 23, 0, 0}, argVWW{nat{0, 0, 0, 22793}, nat{0, 0, 0, 991}, 23, 0, 0},
argVWW{[]Word{7, 0, 0, 22793}, []Word{0, 0, 0, 991}, 23, 7, 0}, argVWW{nat{7, 0, 0, 22793}, nat{0, 0, 0, 991}, 23, 7, 0},
argVWW{[]Word{0, 0, 0, 0}, []Word{7893475, 7395495, 798547395, 68943}, 0, 0, 0}, argVWW{nat{0, 0, 0, 0}, nat{7893475, 7395495, 798547395, 68943}, 0, 0, 0},
argVWW{[]Word{991, 0, 0, 0}, []Word{7893475, 7395495, 798547395, 68943}, 0, 991, 0}, argVWW{nat{991, 0, 0, 0}, nat{7893475, 7395495, 798547395, 68943}, 0, 991, 0},
argVWW{[]Word{0, 0, 0, 0}, []Word{0, 0, 0, 0}, 894375984, 0, 0}, argVWW{nat{0, 0, 0, 0}, nat{0, 0, 0, 0}, 894375984, 0, 0},
argVWW{[]Word{991, 0, 0, 0}, []Word{0, 0, 0, 0}, 894375984, 991, 0}, argVWW{nat{991, 0, 0, 0}, nat{0, 0, 0, 0}, 894375984, 991, 0},
argVWW{[]Word{_M << 1 & _M}, []Word{_M}, 1 << 1, 0, _M >> (_W - 1)}, argVWW{nat{_M << 1 & _M}, nat{_M}, 1 << 1, 0, _M >> (_W - 1)},
argVWW{[]Word{_M<<1&_M + 1}, []Word{_M}, 1 << 1, 1, _M >> (_W - 1)}, argVWW{nat{_M<<1&_M + 1}, nat{_M}, 1 << 1, 1, _M >> (_W - 1)},
argVWW{[]Word{_M << 7 & _M}, []Word{_M}, 1 << 7, 0, _M >> (_W - 7)}, argVWW{nat{_M << 7 & _M}, nat{_M}, 1 << 7, 0, _M >> (_W - 7)},
argVWW{[]Word{_M<<7&_M + 1<<6}, []Word{_M}, 1 << 7, 1 << 6, _M >> (_W - 7)}, argVWW{nat{_M<<7&_M + 1<<6}, nat{_M}, 1 << 7, 1 << 6, _M >> (_W - 7)},
argVWW{[]Word{_M << 7 & _M, _M, _M, _M}, []Word{_M, _M, _M, _M}, 1 << 7, 0, _M >> (_W - 7)}, argVWW{nat{_M << 7 & _M, _M, _M, _M}, nat{_M, _M, _M, _M}, 1 << 7, 0, _M >> (_W - 7)},
argVWW{[]Word{_M<<7&_M + 1<<6, _M, _M, _M}, []Word{_M, _M, _M, _M}, 1 << 7, 1 << 6, _M >> (_W - 7)}, argVWW{nat{_M<<7&_M + 1<<6, _M, _M, _M}, nat{_M, _M, _M, _M}, 1 << 7, 1 << 6, _M >> (_W - 7)},
} }
func testFunVWW(t *testing.T, msg string, f funVWW, a argVWW) { func testFunVWW(t *testing.T, msg string, f funVWW, a argVWW) {
n := len(a.z) n := len(a.z)
z := make([]Word, n) z := make(nat, n)
c := f(addr(z), addr(a.x), a.y, a.r, n) c := f(addr(z), addr(a.x), a.y, a.r, n)
for i, zi := range z { for i, zi := range z {
if zi != a.z[i] { if zi != a.z[i] {
...@@ -232,16 +232,16 @@ func testFunVWW(t *testing.T, msg string, f funVWW, a argVWW) { ...@@ -232,16 +232,16 @@ func testFunVWW(t *testing.T, msg string, f funVWW, a argVWW) {
type funWVW func(z *Word, xn Word, x *Word, y Word, n int) (r Word) type funWVW func(z *Word, xn Word, x *Word, y Word, n int) (r Word)
type argWVW struct { type argWVW struct {
z []Word z nat
xn Word xn Word
x []Word x nat
y Word y Word
r Word r Word
} }
func testFunWVW(t *testing.T, msg string, f funWVW, a argWVW) { func testFunWVW(t *testing.T, msg string, f funWVW, a argWVW) {
n := len(a.z) n := len(a.z)
z := make([]Word, n) z := make(nat, n)
r := f(addr(z), a.xn, addr(a.x), a.y, n) r := f(addr(z), a.xn, addr(a.x), a.y, n)
for i, zi := range z { for i, zi := range z {
if zi != a.z[i] { if zi != a.z[i] {
......
...@@ -10,7 +10,7 @@ package big ...@@ -10,7 +10,7 @@ package big
// The zero value for an Int represents the value 0. // The zero value for an Int represents the value 0.
type Int struct { type Int struct {
neg bool // sign neg bool // sign
abs []Word // absolute value of the integer abs nat // absolute value of the integer
} }
...@@ -21,7 +21,7 @@ func (z *Int) New(x int64) *Int { ...@@ -21,7 +21,7 @@ func (z *Int) New(x int64) *Int {
z.neg = true z.neg = true
x = -x x = -x
} }
z.abs = newN(z.abs, uint64(x)) z.abs = z.abs.new(uint64(x))
return z return z
} }
...@@ -33,7 +33,7 @@ func NewInt(x int64) *Int { return new(Int).New(x) } ...@@ -33,7 +33,7 @@ func NewInt(x int64) *Int { return new(Int).New(x) }
// Set sets z to x. // Set sets z to x.
func (z *Int) Set(x *Int) *Int { func (z *Int) Set(x *Int) *Int {
z.neg = x.neg z.neg = x.neg
z.abs = setN(z.abs, x.abs) z.abs = z.abs.set(x.abs)
return z return z
} }
...@@ -44,16 +44,16 @@ func (z *Int) Add(x, y *Int) *Int { ...@@ -44,16 +44,16 @@ func (z *Int) Add(x, y *Int) *Int {
// x + y == x + y // x + y == x + y
// (-x) + (-y) == -(x + y) // (-x) + (-y) == -(x + y)
z.neg = x.neg z.neg = x.neg
z.abs = addNN(z.abs, x.abs, y.abs) z.abs = z.abs.add(x.abs, y.abs)
} else { } else {
// x + (-y) == x - y == -(y - x) // x + (-y) == x - y == -(y - x)
// (-x) + y == y - x == -(x - y) // (-x) + y == y - x == -(x - y)
if cmpNN(x.abs, y.abs) >= 0 { if x.abs.cmp(y.abs) >= 0 {
z.neg = x.neg z.neg = x.neg
z.abs = subNN(z.abs, x.abs, y.abs) z.abs = z.abs.sub(x.abs, y.abs)
} else { } else {
z.neg = !x.neg z.neg = !x.neg
z.abs = subNN(z.abs, y.abs, x.abs) z.abs = z.abs.sub(y.abs, x.abs)
} }
} }
if len(z.abs) == 0 { if len(z.abs) == 0 {
...@@ -69,16 +69,16 @@ func (z *Int) Sub(x, y *Int) *Int { ...@@ -69,16 +69,16 @@ func (z *Int) Sub(x, y *Int) *Int {
// x - (-y) == x + y // x - (-y) == x + y
// (-x) - y == -(x + y) // (-x) - y == -(x + y)
z.neg = x.neg z.neg = x.neg
z.abs = addNN(z.abs, x.abs, y.abs) z.abs = z.abs.add(x.abs, y.abs)
} else { } else {
// x - y == x - y == -(y - x) // x - y == x - y == -(y - x)
// (-x) - (-y) == y - x == -(x - y) // (-x) - (-y) == y - x == -(x - y)
if cmpNN(x.abs, y.abs) >= 0 { if x.abs.cmp(y.abs) >= 0 {
z.neg = x.neg z.neg = x.neg
z.abs = subNN(z.abs, x.abs, y.abs) z.abs = z.abs.sub(x.abs, y.abs)
} else { } else {
z.neg = !x.neg z.neg = !x.neg
z.abs = subNN(z.abs, y.abs, x.abs) z.abs = z.abs.sub(y.abs, x.abs)
} }
} }
if len(z.abs) == 0 { if len(z.abs) == 0 {
...@@ -94,7 +94,7 @@ func (z *Int) Mul(x, y *Int) *Int { ...@@ -94,7 +94,7 @@ func (z *Int) Mul(x, y *Int) *Int {
// x * (-y) == -(x * y) // x * (-y) == -(x * y)
// (-x) * y == -(x * y) // (-x) * y == -(x * y)
// (-x) * (-y) == x * y // (-x) * (-y) == x * y
z.abs = mulNN(z.abs, x.abs, y.abs) z.abs = z.abs.mul(x.abs, y.abs)
z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
return z return z
} }
...@@ -126,14 +126,14 @@ func (z *Int) DivMod(x, y, r *Int) (*Int, *Int) { ...@@ -126,14 +126,14 @@ func (z *Int) DivMod(x, y, r *Int) (*Int, *Int) {
func div(q, r, x, y *Int) { func div(q, r, x, y *Int) {
q.neg = x.neg != y.neg q.neg = x.neg != y.neg
r.neg = x.neg r.neg = x.neg
q.abs, r.abs = divNN(q.abs, r.abs, x.abs, y.abs) q.abs, r.abs = q.abs.div(r.abs, x.abs, y.abs)
return return
} }
// Neg computes z = -x. // Neg computes z = -x.
func (z *Int) Neg(x *Int) *Int { func (z *Int) Neg(x *Int) *Int {
z.abs = setN(z.abs, x.abs) z.abs = z.abs.set(x.abs)
z.neg = len(z.abs) > 0 && !x.neg // 0 has no sign z.neg = len(z.abs) > 0 && !x.neg // 0 has no sign
return z return z
} }
...@@ -152,7 +152,7 @@ func (x *Int) Cmp(y *Int) (r int) { ...@@ -152,7 +152,7 @@ func (x *Int) Cmp(y *Int) (r int) {
// (-x) cmp (-y) == -(x cmp y) // (-x) cmp (-y) == -(x cmp y)
switch { switch {
case x.neg == y.neg: case x.neg == y.neg:
r = cmpNN(x.abs, y.abs) r = x.abs.cmp(y.abs)
if x.neg { if x.neg {
r = -r r = -r
} }
...@@ -170,7 +170,7 @@ func (z *Int) String() string { ...@@ -170,7 +170,7 @@ func (z *Int) String() string {
if z.neg { if z.neg {
s = "-" s = "-"
} }
return s + stringN(z.abs, 10) return s + z.abs.string(10)
} }
...@@ -212,7 +212,7 @@ func (z *Int) SetString(s string, base int) (*Int, bool) { ...@@ -212,7 +212,7 @@ func (z *Int) SetString(s string, base int) (*Int, bool) {
z.neg = false z.neg = false
} }
z.abs, _, scanned = scanN(z.abs, s, base) z.abs, _, scanned = z.abs.scan(s, base)
if scanned != len(s) { if scanned != len(s) {
goto Error goto Error
} }
...@@ -230,7 +230,7 @@ Error: ...@@ -230,7 +230,7 @@ Error:
// sets z to that value. // sets z to that value.
func (z *Int) SetBytes(b []byte) *Int { func (z *Int) SetBytes(b []byte) *Int {
s := int(_S) s := int(_S)
z.abs = makeN(z.abs, (len(b)+s-1)/s, false) z.abs = z.abs.make((len(b)+s-1)/s, false)
z.neg = false z.neg = false
j := 0 j := 0
...@@ -258,7 +258,7 @@ func (z *Int) SetBytes(b []byte) *Int { ...@@ -258,7 +258,7 @@ func (z *Int) SetBytes(b []byte) *Int {
z.abs[j] = w z.abs[j] = w
} }
z.abs = normN(z.abs) z.abs = z.abs.norm()
return z return z
} }
...@@ -306,12 +306,12 @@ func (z *Int) Exp(x, y, m *Int) *Int { ...@@ -306,12 +306,12 @@ func (z *Int) Exp(x, y, m *Int) *Int {
return z return z
} }
var mWords []Word var mWords nat
if m != nil { if m != nil {
mWords = m.abs mWords = m.abs
} }
z.abs = expNNN(z.abs, x.abs, y.abs, mWords) z.abs = z.abs.expNN(x.abs, y.abs, mWords)
z.neg = x.neg && y.abs[0]&1 == 1 z.neg = x.neg && y.abs[0]&1 == 1
return z return z
} }
...@@ -379,20 +379,20 @@ func GcdInt(d, x, y, a, b *Int) { ...@@ -379,20 +379,20 @@ func GcdInt(d, x, y, a, b *Int) {
// ProbablyPrime performs n Miller-Rabin tests to check whether z is prime. // ProbablyPrime performs n Miller-Rabin tests to check whether z is prime.
// If it returns true, z is prime with probability 1 - 1/4^n. // If it returns true, z is prime with probability 1 - 1/4^n.
// If it returns false, z is not prime. // If it returns false, z is not prime.
func ProbablyPrime(z *Int, n int) bool { return !z.neg && probablyPrime(z.abs, n) } func ProbablyPrime(z *Int, n int) bool { return !z.neg && z.abs.probablyPrime(n) }
// Lsh sets z = x << n and returns z. // Lsh sets z = x << n and returns z.
func (z *Int) Lsh(x *Int, n uint) *Int { func (z *Int) Lsh(x *Int, n uint) *Int {
addedWords := int(n) / _W addedWords := int(n) / _W
// Don't assign z.abs yet, in case z == x // Don't assign z.abs yet, in case z == x
znew := makeN(z.abs, len(x.abs)+addedWords+1, false) znew := z.abs.make(len(x.abs)+addedWords+1, false)
z.neg = x.neg z.neg = x.neg
shiftLeft(znew[addedWords:], x.abs, n%_W) znew[addedWords:].shiftLeft(x.abs, n%_W)
for i := range znew[0:addedWords] { for i := range znew[0:addedWords] {
znew[i] = 0 znew[i] = 0
} }
z.abs = normN(znew) z.abs = znew.norm()
return z return z
} }
...@@ -401,9 +401,9 @@ func (z *Int) Lsh(x *Int, n uint) *Int { ...@@ -401,9 +401,9 @@ func (z *Int) Lsh(x *Int, n uint) *Int {
func (z *Int) Rsh(x *Int, n uint) *Int { func (z *Int) Rsh(x *Int, n uint) *Int {
removedWords := int(n) / _W removedWords := int(n) / _W
// Don't assign z.abs yet, in case z == x // Don't assign z.abs yet, in case z == x
znew := makeN(z.abs, len(x.abs)-removedWords, false) znew := z.abs.make(len(x.abs)-removedWords, false)
z.neg = x.neg z.neg = x.neg
shiftRight(znew, x.abs[removedWords:], n%_W) znew.shiftRight(x.abs[removedWords:], n%_W)
z.abs = normN(znew) z.abs = znew.norm()
return z return z
} }
...@@ -327,8 +327,8 @@ func TestDivStepD6(t *testing.T) { ...@@ -327,8 +327,8 @@ func TestDivStepD6(t *testing.T) {
// See Knuth, Volume 2, section 4.3.1, exercise 21. This code exercises // See Knuth, Volume 2, section 4.3.1, exercise 21. This code exercises
// a code path which only triggers 1 in 10^{-19} cases. // a code path which only triggers 1 in 10^{-19} cases.
u := &Int{false, []Word{0, 0, 1 + 1<<(_W-1), _M ^ (1 << (_W - 1))}} u := &Int{false, nat{0, 0, 1 + 1<<(_W-1), _M ^ (1 << (_W - 1))}}
v := &Int{false, []Word{5, 2 + 1<<(_W-1), 1 << (_W - 1)}} v := &Int{false, nat{5, 2 + 1<<(_W-1), 1 << (_W - 1)}}
r := new(Int) r := new(Int)
q, r := new(Int).DivMod(u, v, r) q, r := new(Int).DivMod(u, v, r)
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment