Assuming that your code as written doesn't use any "illegal" operations (i.e. you are OK with +1), then you can write
#include <stdio.h>
int main(void) {
int x, y, z;
int mxy, mxyz;
x = 5;
y = 123;
z = 9;
mxy = x - ((x - y) & ((x - y) >> 31)); // max(x, y)
mxyz = mxy - ((mxy - z) & ((mxy - z) >> 31));
printf("max is %d\n", mxyz);
}
Only 10 operations. Every -
can be replaced with a ~
and +1
adding a further 6 operations. I will leave that as an exercise. Point is - you don't need to evaluate max(x,y)
and max(y,z)
and max(x,z)
separately. max(x,y,z) = max(max(x,y),z)
... and that's where your savings come from.
UPDATE using only +1
and bitwise operators:
#include <stdio.h>
int main(void) {
unsigned int x, y, z, r;
unsigned int mxy, mxyz;
unsigned int xmy;
unsigned int mxymz;
x = 5;
y = 123;
z = 9;
xmy = x + (~y+1); // x minus y
mxy = x + ~(xmy & (xmy >> 31)) + 1; // max(x, y)
mxymz = mxy + (~z+1); // max(x,y) minus z
mxyz = mxy + (~(mxymz & (mxymz >> 31))+1); // max(x,y,z)
printf("max is %d\n", mxyz);
}
Total of 16 operations (plus 3 intermediate assignments to variables, if you're counting those). Using only + ~ >>
. I think that counts.
A couple of points:
- the hard-wired value
31
really should be sizeof(int) * CHAR_BIT - 1
- You should be using unsigned integers since the
>>31
operation is not recommended on signed integers (see https://www.securecoding.cert.org/confluence/display/seccode/INT13-C.+Use+bitwise+operators+only+on+unsigned+operands )