ack icon indicating copy to clipboard operation
ack copied to clipboard

Modula-2: wrong value of 31 MOD (-10)

Open kernigh opened this issue 8 years ago • 0 comments

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.

kernigh avatar Oct 20 '17 19:10 kernigh