kent@xanth.cs.odu.edu (Kent Paul Dolan) (02/13/88)
In article <6413@j.cc.purdue.edu> ags@j.cc.purdue.edu.UUCP (Dave Seaman) writes: >In article <8802101656.AA08424@decwrl.dec.com> fulton@navion.dec.com (10-Feb-1988 0957) writes: [lots omitted] >> Then you have -1 MOD 7 => -1, which does not equate to any of >> the numbers assigned to Sunday thru Saturday, namely 0 thru 6. >I don't have my copy of the Modula-2 standard available at the moment, but >I believe that the definition of the MOD operator is similar to Pascal, >where the standard says: > > A term of the form i mod j shall be an error if j is zero or > negative, otherwise the value of i mod j shall be that value of > (i-(k*j)) for integral k such that 0 <= i mod j < j. > >Therefore the correct value of (-1 MOD 7) is 6, not -1. In fact, I believe >that in Modula-2 the result of the MOD operator is type CARDINAL and >therefore cannot be negative. It sounds as if you may be stuck with a >flawed implementation of Modula-2. Sadly, the flaw is in Wirth's design, not Logitech's implementation. I don't have his 3rd Edition Modula-2 reference manual handy (it's out on loan), but I read it through in January, and was incredulous that he would chose an implementation of MOD that is negative or zero to the left of the origin (in y = x MOD modulus coordinates) and positive or zero to the right of the origin, but there it was in print. I quickly took out my copy of the BENCHMARK Modula-2 compiler for the Amiga, and wrote my first program to test this design flaw. The program worked as the book explained. Aaaaargh. I have run into the same problem in other languages (FORTRAN IV for the HP 1000 many years ago comes to mind), and the work-around is always the same: y = ((x MOD modulus) + modulus) MOD modulus. Gag! It appears Wirth was too seduced by the beauty of the "identity" x = modulus * ( x DIV modulus ) + ( x MOD modulus ) [which is how he defines MOD] to notice that the resulting modulus function is flawed for any normal use (Life games on a 0..n-1 by 0..n-1 toroid, where the value of cell (0,0) depends on the value of "cell" (-1 MOD n,-1 MOD n) = (n-1,n-1), for example, or array-implemented ring queues, where one wants to be able to index backward past the queue's origin and still stay within the queue). Even the giants have feet of clay, I guess. I have been unable to communicate this problem to Dr. Wirth, so if one of the European readers knows a forwarding address, by all means send this note along to him. Kent, the man from xanth.
claudio@forty2.UUCP (Claudio Nieder) (02/17/88)
In article <4057@xanth.cs.odu.edu> kent@xanth.UUCP (Kent Paul Dolan) writes: > ... >It appears Wirth was too seduced by the beauty of the "identity" x = >modulus * ( x DIV modulus ) + ( x MOD modulus ) [which is how he >defines MOD]... I think the above mentioned "identity" is quite right, the problem is how you define x DIV modulus. In PIM3 Wirth defines: "Integer division is denoted by DIV and truncates the quotient. For example ... -15 DIV 4= -3" but there seems some room for changes. On his compiler for the CERES (a NS32032 based Workstation built at the ETH) he redefined that, thus now -15 DIV 4=-4 and -15 MOD 4=1 I have read in some paper that dealt with the proposed BSI Modula-2 standard that Wirth suggested/considered/approved/wasn't against the following solution (perhaps somebody who has acces to the BSI papers may tell more about that): -15 DIV 4=-4, -15 MOD 4=1 -15 / 4=-3, -15 REM 4=-3 On CERES DIV, MOD and "/" are implemented as mentioned above while "REM" is not implemented. The way how you actually implement it may also be influenced by the underlying Processor. On the NS32032 both definitions of DIV and MOD exist, thus it is quite easy to provide both. The MC68000 Processor provides only the "/",REM variant. Therefor on the M2Amiga compiler, which implements both variants, "/" and REM simply use the processors DIVS instruction while DIV and MOD generate more complex code. claudio