I have had much use for expressions of the form A[a%16] where A is declared as “zot A[16];”. If 0≤a%b<b whenever b>0 then this expression is valid whether or not a<0. If (−5)/16 is −1, as I propose, then (−5)%16 = (−5) − ((−5)/16)*16 = (−5) − (−1*16) = 11 and thus A[11] is valid and what the logic of program expects.
Here are some identities that work only with rounding down:
One rule that is lost by rounding down is that a/−b = (−a)/b = −(a/b). I have not found that rule nearly as useful as the above mechanisms.
I have done much systems and physics programming and have found that signed integers are nearly unneeded in systems programing signed floats are but needed greatly in physics and the geometry that frequently accompanies physics. Computer graphics also uses signed numbers and probably signed integers heavily.
The proposal can be summarized merely as “round the quotient down (towards minus infinity) and define a%b = a − (a/b)*b”.
For applications that need both a/b and a%b most C compilers will program the division twice. Here is a hack that modifies the language “transparently” to the user and solves the problem. Define a new type “typedef struct{int q; int r;} IQ;” Define a new built-in operation “IQ divide(int num, int den);”. Define “a/b” as “divide(a,b).q” and “a%b” as “divide(a,b).r”. Now the end user (programmer) expression “func(a/b, a%b)” expands to “func(divide(a,b).q,divide(a,b).r)”. The latter expression has a repeated subexpression which is found by normal compiler logic and only one divide is done. The user can make use of this type and built-in function as well if is spelled so that he can use it. I now notice that ISO’s C has very much this function with the functions
#include <stdlib.h> typedef ... dif_t; typedef ... ldiv_t; div_t div(int, int); ldiv_t ldiv(long, long);
The same trick works for pairs of function such as sin(x) and cos(x) which are frequently invoked in pairs and can be computed efficiently together.