From 0023c4f1f68c1c423d8d3563bccff8ce92a64d9d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Sun, 5 Apr 2020 17:34:14 +0300 Subject: [PATCH] vm: use truncated division in MOD Mimic C#'s `%` behavior. Related 4b44190 (#773). --- pkg/vm/vm.go | 2 +- pkg/vm/vm_test.go | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 13ac42441..555deb8ce 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -794,7 +794,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro a := v.estack.Pop().BigInt() v.checkBigIntSize(a) - v.estack.PushVal(new(big.Int).Mod(a, b)) + v.estack.PushVal(new(big.Int).Rem(a, b)) case opcode.SHL, opcode.SHR: b := v.estack.Pop().BigInt().Int64() diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index e0b13920b..26cebd624 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -844,11 +844,10 @@ func TestMULBigResult(t *testing.T) { checkVMFailed(t, vm) } -func TestDiv(t *testing.T) { - prog := makeProgram(opcode.DIV) - runCase := func(p, q, result int64) func(t *testing.T) { +func TestDivMod(t *testing.T) { + runCase := func(op opcode.Opcode, p, q, result int64) func(t *testing.T) { return func(t *testing.T) { - vm := load(prog) + vm := load(makeProgram(op)) vm.estack.PushVal(p) vm.estack.PushVal(q) runVM(t, vm) @@ -856,10 +855,19 @@ func TestDiv(t *testing.T) { } } - t.Run("positive/positive", runCase(5, 2, 2)) - t.Run("positive/negative", runCase(5, -2, -2)) - t.Run("negative/positive", runCase(-5, 2, -2)) - t.Run("negative/negative", runCase(-5, -2, 2)) + t.Run("DIV", func(t *testing.T) { + t.Run("positive/positive", runCase(opcode.DIV, 5, 2, 2)) + t.Run("positive/negative", runCase(opcode.DIV, 5, -2, -2)) + t.Run("negative/positive", runCase(opcode.DIV, -5, 2, -2)) + t.Run("negative/negative", runCase(opcode.DIV, -5, -2, 2)) + }) + + t.Run("MOD", func(t *testing.T) { + t.Run("positive/positive", runCase(opcode.MOD, 5, 2, 1)) + t.Run("positive/negative", runCase(opcode.MOD, 5, -2, 1)) + t.Run("negative/positive", runCase(opcode.MOD, -5, 2, -1)) + t.Run("negative/negative", runCase(opcode.MOD, -5, -2, -1)) + }) }