AMG: In Tcl, integer division always rounds down, even in the face of negative numbers.
expr { 20 / 6} ;# 3
expr { 20 / -6} ;# -4
expr {-20 / 6} ;# -4
expr {-20 / -6} ;# 3C does not provide this guarantee. On all platforms, GCC defines negative integer division to round toward zero, which is not mathematically useful. Portably, the div() [1] family of functions can be used to get this same wonky but predictable behavior. To get nice round-down behavior, fix up the result of div():#include <stdlib.h>
int mydiv(int num, int den)
{
div_t result = div(num, den);
if (result.rem < 0) {
return result.quot - 1;
} else {
return result.quot;
}
}Or avoid div() and take matters into your own hands:int mydiv(int num, int den)
{
switch (((num < 0) << 1) | (den < 0)) {
case 0: return num / den; /* +/+ */
case 1: return -((num - den - 1) / -den); /* +/- */
case 2: return -((-num + den - 1) / den); /* -/+ */
case 3: return -num / -den; /* -/- */
}
}Here's how Tcl does it (see tclExecute.c [2]):quot = num / den;
if (((quot < 0) || ((quot == 0) &&
((num < 0 && den > 0) || (num > 0 && den < 0)))) &&
((quot * den) != num)) {
quot -= 1;
}
return quot;I don't quite understand this. It appears to assume that C division rounds toward zero, then decrements negative results to instead round down. But what if C division rounds down? Maybe Tcl simply doesn't support any compilers that allow this behavior. I hear a rumor that recent compilers all round toward zero, for instance GCC.