Skip to content

Commit 78905e8

Browse files
authored
Add DivMod() (#113)
DivMod() sets z to the quotient x div y and m to the modulus x mod y and returns the pair (z, m) for y != 0. If y == 0, both z and m are set to 0 (OBS: differs from the big.Int). Closes #103.
1 parent 77643b2 commit 78905e8

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

uint256.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,20 @@ func (z *Int) Mod(x, y *Int) *Int {
588588
}
589589

590590
var quot Int
591-
rem := udivrem(quot[:], x[:], y)
592-
return z.Set(&rem)
591+
*z = udivrem(quot[:], x[:], y)
592+
return z
593+
}
594+
595+
// DivMod sets z to the quotient x div y and m to the modulus x mod y and returns the pair (z, m) for y != 0.
596+
// If y == 0, both z and m are set to 0 (OBS: differs from the big.Int)
597+
func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
598+
if y.IsZero() {
599+
return z.Clear(), m.Clear()
600+
}
601+
var quot Int
602+
*m = udivrem(quot[:], x[:], y)
603+
*z = quot
604+
return z, m
593605
}
594606

595607
// SMod interprets x and y as two's complement signed integers,

uint256_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ func TestRandomBinOp(t *testing.T) {
260260
t.Run("Mod", func(t *testing.T) { testRandomOp(t, (*Int).Mod, bigMod) })
261261
t.Run("SDiv", func(t *testing.T) { testRandomOp(t, (*Int).SDiv, bigSDiv) })
262262
t.Run("SMod", func(t *testing.T) { testRandomOp(t, (*Int).SMod, bigSMod) })
263+
t.Run("DivMod/Div", func(t *testing.T) { testRandomOp(t, divModDiv, bigDiv) })
264+
t.Run("DivMod/Mod", func(t *testing.T) { testRandomOp(t, divModMod, bigMod) })
263265
t.Run("udivrem/Div", func(t *testing.T) { testRandomOp(t, udivremDiv, bigDiv) })
264266
t.Run("udivrem/Mod", func(t *testing.T) { testRandomOp(t, udivremMod, bigMod) })
265267
}
@@ -298,6 +300,19 @@ func TestRandomSquare(t *testing.T) {
298300
)
299301
}
300302

303+
// divModDiv wraps DivMod and returns quotient only
304+
func divModDiv(z, x, y *Int) *Int {
305+
var m Int
306+
z.DivMod(x, y, &m)
307+
return z
308+
}
309+
310+
// divModMod wraps DivMod and returns modulus only
311+
func divModMod(z, x, y *Int) *Int {
312+
new(Int).DivMod(x, y, z)
313+
return z
314+
}
315+
301316
// udivremDiv wraps udivrem and returns quotient
302317
func udivremDiv(z, x, y *Int) *Int {
303318
var quot Int
@@ -1243,6 +1258,8 @@ func TestBinOp(t *testing.T) {
12431258
t.Run("Mod", func(t *testing.T) { proc(t, (*Int).Mod, bigMod) })
12441259
t.Run("SDiv", func(t *testing.T) { proc(t, (*Int).SDiv, bigSDiv) })
12451260
t.Run("SMod", func(t *testing.T) { proc(t, (*Int).SMod, bigSMod) })
1261+
t.Run("DivMod/Div", func(t *testing.T) { proc(t, divModDiv, bigDiv) })
1262+
t.Run("DivMod/Mod", func(t *testing.T) { proc(t, divModMod, bigMod) })
12461263
t.Run("udivrem/Div", func(t *testing.T) { proc(t, udivremDiv, bigDiv) })
12471264
t.Run("udivrem/Mod", func(t *testing.T) { proc(t, udivremMod, bigMod) })
12481265
t.Run("Exp", func(t *testing.T) { proc(t, (*Int).Exp, bigExp) })

0 commit comments

Comments
 (0)