Return 1 if any even bit is set to 1 using only bitwise and logical operators

I am currently stuck on a function that I need to write that checks if any even numbered bits are set to 1. For example, evenBit(0x1) returns 1, evenBit(0x2) returns 0, and evenBit(0xFFFFFFFF) returns 1. Currently my evenBit() function looks like this:

unsigned int evenBit(unsigned int x) {
    unsigned int evenMask = 0x55555555;
    return x & evenMask;
}

But these aren't returning the results that I was expecting but I'm not entirely sure how to approach this. I want to isolate the even bits with the mask, which I've done, but I'm not sure what to do with the result after so that it will become 1. I can use only bitwise and logical operators (&, |, !); no if statements, loops, arithmetic operators (+, -, *, /, %), or conditional operators (==, !=, etc).


Solution 1:

Your posted code is already correct in the sense that the function evenBit will return a nonzero value (true) if any of the bits are set, and zero (false) if not.

If you want to restrict the return values to 0 and 1, then you can change the line

return x & evenMask;

to:

return !!( x & evenMask );

This will apply the logical-NOT operator ! twice.

The logical-NOT operator will evaluate to 0 if its operand is nonzero, and to 1 if its operand is zero. Therefore, this operation gives you the exact opposite of the result that you want. Applying the logical-NOT operator a second time will give you the desired result.

Normally, a programmer would write

return ( x & evenMask ) != 0;

or

return ( x & evenMask ) ? 1 : 0;

to achieve the exact same result, however this would violate the restrictions stated in your question of only using bitwise and logical operators.

Solution 2:

Using only bitwise operators (and assignments) as requested,

x |= x >> 16;
x |= x >>  8;
x |= x >>  4;
x |= x >>  2;
return x & 1;

Like the OP, I assumed x is a 32-bit unsigned int, though that isn't guaranteed. An unsigned int could be smaller or larger.