I have a question very similar to the one here Checking bits of ints to see if they share binary with the power of 2 (bitwise only) , however the question was frankly poorly worded (so i'm not sure how similar they are) and the answer was not explained much.
Trying to replicate this function:
int testdl4(int x) {
int i;
for (i = 1; i < 32; i+=2)
if ((x & (1<<i)) == 0)
return 0;
return 1;
}
Using only these bit-wise operators: !, ~, &, ^, |, +, <<, and >> (Meaning no loops or if statements either).
The answer on aforementioned link (Same question I think, but with loop starting at 0) was:
return !((x & 0x55555555) ^ 0x55555555);
And I believe the mask needs to be changed to get it to work, but I am not sure 2 what.
Could someone please solve & explain reasoning?
Let's start by writing what your code actually does, in English:
If any odd numbered bit (from 1 to 31) is clear return 0; otherwise return 1.
Now "any odd numbered bit (from 1 to 31)
" is the binary value 10101010101010101010101010101010b, which is 0xAAAAAAAAUL
. Note that this value is not possible for signed 32-bit integers, so we want to use unsigned integers that are at least 32 bits.
If any bit is clear, then x & 0xAAAAAAAAUL
won't be equal to 0xAAAAAAAAUL
.
That gives:
int testdl4(unsigned long x) {
if( (x & 0xAAAAAAAAUL) != 0xAAAAAAAAUL) {
return 0;
}
return 1;
}
Note that this does include an if
to get the same behavior as your original code (e.g. returning 1
and not returning a messed up non-zero value).
However, the logical NOT !
will force a non-zero value to become zero and a zero value to become 1; so you can do:
int testdl4(unsigned long x) {
return !((x & 0xAAAAAAAAUL) ^ 0xAAAAAAAAUL);
}