June 23, 2004

Another non-branching integer abs

Thorbjørn Willoch suggested that I add r = (v ^ (v >> (sizeof(int) * 8 - 1))) + ((unsigned) v >> (sizeof(int) * 8 - 1)) for anyone interested in avoiding the patented method for computing the integer absolute value without branching, though his takes another operation.   I added my own variation of it, r = (v ^ (v >> (sizeof(int) * 8 - 1))) + (v < 0), which takes as many operations, though gcc generated fewer x86 instructions for it (4) than his (5).  The patented version is still the best at 3. Another variation came to mind, but I didn't think it sufficiently portable:
union {long long ll; int i[2];} t;
t.ll = v; // sign-extend
r = (t.i[0] ^ t.i[1]) - t.i[ BYTE_ORDER == LITTLE_ENDIAN];
Posted by seander at June 23, 2004 10:25 PM
Comments