diff --git a/src/runtime/SYSTEM.c b/src/runtime/SYSTEM.c index a1b2cb14..39c09fe7 100644 --- a/src/runtime/SYSTEM.c +++ b/src/runtime/SYSTEM.c @@ -37,13 +37,13 @@ INT64 SYSTEM_DIV(INT64 x, INT64 y) INT64 SYSTEM_MOD(INT64 x, INT64 y) { - if (x == 0) return 0; - if (x >= 0) - if (y >= 0) {return x % y;} - else {return (y+1) + ((x-1) % (-y));} - else - if (y >= 0) {return (y-1) - ((-x-1) % y);} - else {return -((-x) % (-y));} + if (x == 0) {return 0;} + INT64 m = x % y; + if (m < 0) + { + m = (y < 0) ? m - y : m + y; + } + return m; } INT64 SYSTEM_ENTIER(double x) diff --git a/src/test/confidence/language/TestLanguage.mod b/src/test/confidence/language/TestLanguage.mod index 7399b006..be09a50a 100644 --- a/src/test/confidence/language/TestLanguage.mod +++ b/src/test/confidence/language/TestLanguage.mod @@ -4,6 +4,8 @@ IMPORT SYSTEM, Console; VAR gz: LONGREAL; +PROCEDURE -cpumod(x, y: INTEGER): INTEGER "(INT64)(x % y)"; + PROCEDURE TestShiftResult(of, by, actual, expected: LONGINT; msg: ARRAY OF CHAR); BEGIN IF actual # expected THEN @@ -172,7 +174,7 @@ END TestValue; PROCEDURE side(i: INTEGER): INTEGER; BEGIN RETURN i END side; PROCEDURE DivMod; - VAR i,j: INTEGER; + VAR i,j, m: INTEGER; BEGIN j := 2; i := 4; TestValue(i DIV j, 2, "4 DIV 2"); TestValue(side(i) DIV side(j), 2, "side(4) DIV side(2)"); @@ -203,20 +205,44 @@ BEGIN i := 6; j := 3; TestValue(i MOD j, i - ((i DIV j) * j), "6 MOD 3"); i := 7; j := 3; TestValue(i MOD j, i - ((i DIV j) * j), "7 MOD 3"); - i := -4; j := 3; TestValue(i MOD j, i - ((i DIV j) * j), "-4 MOD 3"); - i := -5; j := 3; TestValue(i MOD j, i - ((i DIV j) * j), "-5 MOD 3"); - i := -6; j := 3; TestValue(i MOD j, i - ((i DIV j) * j), "-6 MOD 3"); - i := -7; j := 3; TestValue(i MOD j, i - ((i DIV j) * j), "-7 MOD 3"); + i := -4; j := 3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "-4 MOD 3"); + i := -5; j := 3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "-5 MOD 3"); + i := -6; j := 3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "-6 MOD 3"); + i := -7; j := 3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "-7 MOD 3"); - i := 4; j := -3; TestValue(i MOD j, i - ((i DIV j) * j), "4 MOD -3"); - i := 5; j := -3; TestValue(i MOD j, i - ((i DIV j) * j), "5 MOD -3"); - i := 6; j := -3; TestValue(i MOD j, i - ((i DIV j) * j), "6 MOD -3"); - i := 7; j := -3; TestValue(i MOD j, i - ((i DIV j) * j), "7 MOD -3"); + i := 4; j := -3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "4 MOD -3"); + i := 5; j := -3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "5 MOD -3"); + i := 6; j := -3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "6 MOD -3"); + i := 7; j := -3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "7 MOD -3"); - i := -4; j := -3; TestValue(i MOD j, i - ((i DIV j) * j), "-4 MOD -3"); - i := -5; j := -3; TestValue(i MOD j, i - ((i DIV j) * j), "-5 MOD -3"); - i := -6; j := -3; TestValue(i MOD j, i - ((i DIV j) * j), "-6 MOD -3"); - i := -7; j := -3; TestValue(i MOD j, i - ((i DIV j) * j), "-7 MOD -3"); + i := -4; j := -3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "-4 MOD -3"); + i := -5; j := -3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "-5 MOD -3"); + i := -6; j := -3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "-6 MOD -3"); + i := -7; j := -3; + m := cpumod(i, j); IF m < 0 THEN IF j < 0 THEN m := m - j ELSE m := m + j END END; + TestValue(i MOD j, m, "-7 MOD -3"); END DivMod;