Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxl!houxm!vax135!cornell!uw-beaver!tektronix!hplabs!sri-unix!cosell@BBN-LABS-B.ARPA From: cosell@BBN-LABS-B.ARPA Newsgroups: net.lang.c Subject: Re: modulus fn with negatives Message-ID: <13338@sri-arpa.UUCP> Date: Sun, 9-Sep-84 22:42:27 EDT Article-I.D.: sri-arpa.13338 Posted: Sun Sep 9 22:42:27 1984 Date-Received: Fri, 14-Sep-84 05:44:36 EDT Lines: 27 I has been my observation (over quite a few machines) that all you can hope for is that '/' and '%' agree. That is, for any I and M, all you can count on is that I = (I/M) * M + (I%M). This may seem obvious, but it is certainly possible to bollix up the signs of things so that, for example, you might have I = ... '+' I%M if M>0, but I = ... '-' I%M if M<0. In any event, the few hardware folk I've talked to about this seem to believe that once the above 'reassembly' equation is satisfied, they don't care any more. Mostly I've found that the compiler writers are the same way, though: '/' gets you the 'quotient' from the machines native 'integer divide' instructions, '%' gets you the 'remainder' from that instruction. Pleas that they are just perpetuating the mathematical unsophistication of the hardware designers fall on deaf ears. The heart of the misunderstanding is that some folk seem to beliave that a proper 'invariant' for the mod function should be: ((-1)*a) mod M = -1 * (a mod M). This is INCORRECT!!! The proper invariant (as any mathematician will tell you) is that a mod M = (a - M) mod M = (a + M) mod M Notice that this latter invariant is violated by most of the dumb-remainder implementations. I've mostly given up: I brute-force make my numbers all be postive (saving the signs away), do '/' or '%' (which is usually predictable and correct for all-positive operands), and then do a 'switch' to tune things depending on what the signs used to be. /bernie