Bit manipulation, return 0 if x != 0, or nonzero otherwise

I don’t believe it’s possible to solve if you want the code to work without assuming a certain size of int and representation. But this works for 32-bit ints and two’s complement representation:

int is_zero(int x) {
    int zero = (x^x);
    int one = ~(~zero + ~zero);
    int five = one + one + one + one + one;
    int thirtyone = (one << five) + ~zero;
    return ~((x >> thirtyone) | ((~x + one) >> thirtyone));
}

It uses multiple assignments to construct the constants, but the code could be folded into a single expression if necessary.

How it works

(x >> thirtyone) is -1 if x is negative and 0 otherwise.
Similarly, (~x + one) >> thirtyone is -1 if x is positive, and 0 otherwise.

The bitwise or of these two expressions is 0 if x is zero, and -1 otherwise. A bitwise ~ then gives -1 if x is zero, and 0 otherwise.

(Almost) word-size independent solution

It’s not perfectly word-size independent, but one can extend the solution above to work for 16, 32 and 64 bit ints (although still depending on two’s complement representation). The code is careful to not shift more than 15 bits at a time (otherwise the result is undefined behavior if int is 16 bits):

int is_zero(int x) {
    int zero = (x^x);
    int one = ~(~zero + ~zero);
    int four = one + one + one + one;
    int k15 = (one << four) + ~zero;
    return ~((x >> k15 >> k15 >> k15 >> k15 >> k15) |
             ((~x + one) >> k15 >> k15 >> k15 >> k15 >> k15));
}

Leave a Comment