Andrey Vul said:
There is also a branch-free way, but it requires limits.h
(q + r + ((q + r) & INT_MAX))>>1
Plus it suffers if the addition overflows.
I like the conditional variant because it takes me back to the good old
days, where -1 was true in C64 BASIC.
Now, to go OT:
Some timings, FWIW, with gcc 4.4.2 -O2, AMD Athlon64, 100 million
iterations (calculate the total of the maximum of two pseudo-random
numbers), runtime affected by the loading whims of my PC:
code runtime
------------------------------------------ -------
#define MYMAX1(a,b) ((a)<(b)?(b)

a)) 3.311
if (a < b) return b; else return a; 3.340
return ((a>b)*a)+((a<=b)*b); 3.328
return (a + b + ((a + b) & INT_MAX))>>1; 3.339
The first two generated identical assembly, unsurprisingly. They make
use of the "conditional move" instruction, so the assembly for computing
the max is basically:
CMP a,b
CMOV a,b
None of the assembly produced in any of the four tests had any explicit
branches--it was all compares and conditional instructions.
I think the only lesson to be drawn from the timings is, "Sometimes
optimizations don't do what you think they'll do." When it comes to
little things like this, I'm a big fan of just coding it straight and
then optimizing if its required.
Perhaps on a RISCier machine (one without Intel's DOIT instruction

),
the differences would be... existent.
-Beej