Modula-2: wrong value of 31 MOD (-10)
I expect that (a DIV b) * b + (a MOD b) = a
but our Modula-2 compiler fails me when (a > 0) and (b < 0).
It does 31 DIV (-10) = -4 and 31 MOD (-10) = 9.
Because 31 ÷ -10 = -3.1, one may round it to -3 or -4.
If it's -3 then (-3 × -10) + 1 = 31.
If it's -4 then (-4 × -10) + -9 = 31.
So the value of 31 MOD (-10) must be 1 or -9.
It can't be 9.
The compiler forgot to fix the sign from 9 to -9. But if it did fix the sign, then it would still not agree with other Modula-2 compilers.
A document of GNU Modula-2 specifies:
Pim2/3 Pim4 ISO
----------- ----------- ----------------------
lval rval DIV MOD DIV MOD DIV MOD / REM
31 10 3 1 3 1 3 1 3 1
-31 10 -3 -1 -4 9 -4 9 -3 -1
31 -10 -3 1 -3 1 Exception -3 1
-31 -10 3 -1 4 9 Exception 3 -1
I tested MacMETH and ACK and got these results:
MacMETH MacMETH ACK Lua Python
Pim3 Pim4 Pim3 Ruby Tcl
---------- ---------- ---------- ----------
lval rval DIV MOD DIV MOD DIV MOD DIV MOD
31 10 3 1 3 1 3 1 3 1
-31 10 -3 -1 -4 9 -4 9 -4 9
31 -10 -3 1 -3 1 -4 9 -4 -9
-31 -10 3 -1 2 -11 3 -1 3 -1
GNU Modula-2 and MacMETH agree that in Pim3, DIV rounds toward zero and MOD follows sign of 1st operand. (This is like C, awk, bc, and EM.) GNU Modula-2 and MacMETH almost agree about Pim4, except MacMETH strangely has (-31) DIV (-10) = 2. ACK almost agrees with Lua, Python, Ruby, Tcl, where DIV rounds down and MOD follows sign of 2nd operand.
(MacMETH also raises a compiler error if MOD has a negative operand in a constant expression. I got the above results by using MOD with variables.)
I don't have Pim3 or Pim4, but I checked the draft of Modula-2 Revision 2010 (m2r2010), where DIV rounds up or down such that MOD is always positive. This agrees with GNU-Modula 2 Pim4.