Version 5 of /

Updated 2010-08-12 18:36:21 by AMG

The expr division operator, requiring two numeric values (either literally or via variables).

Note that the command form (::tcl::mathop::/) (available beginning in Tcl 8.5) can be used as a unary command, in which case it works as a reciprocal. The numerator is in that case effectively 1.0, since the result is always a double.


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}  ;#  3

C 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() [L1 ] 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 [L2 ]):

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.