Implementing if - else if using bitwise operators

20,339

I assume you meant this for your original if statement.

output = (((test << 31) >> 31) & a) | (((!test << 31) >> 31) & b);

Not in front of test so that this isn't a+b when test is 1 and 0 when test is 0 and I replaced + with | because each case should be 0 except for the one you want.

To do the cascaded if else if else statements you could rewrite the expression so that they are dependent on the previous test.

if (test1)
    output = a
if (!test1 & test2)
    output = b
if (!test1 & !test2 & test3)
    output = c
if (!test1 & !test2 & !test3)
    output = d

This leads to an expression like this for all the if else ifs.

output = (((test1 << 31) >> 31) & a)
         | ((((!test1 & test2) << 31) >> 31) & b)
         | ((((!test1 & !test2 & test3) << 31) >> 31) & c)
         | ((((!test1 & !test2 & !test3) << 31) >> 31) & d)
Share:
20,339
noufal
Author by

noufal

Updated on March 20, 2020

Comments

  • noufal
    noufal about 4 years

    Assume that the value of test is 1 or 0. Here I can implement the following if statement using bitwise operators as below.

    if (test)
        output = a;
    else
        output = b;
    

    Using bit wise operators

    output = (((test << 31) >> 31) & a) | (((test << 31) >> 31) & b);
    

    Now I want to implement the following if statements using bitwise operators.

    if (test1)
        output = a;
    else if (test2)
        output = b;
    else if (test3)
        output = c;
    else
        output = d;
    

    The values of test1, test2, test3 are either 0 or 1.

    Any suggestions to do that ?

  • Lee Daniel Crocker
    Lee Daniel Crocker almost 11 years
    Why the wasteful and unportable ((test << 31) >> 31) instead of (test & 1) ?
  • FDinoff
    FDinoff almost 11 years
    @LeeDanielCrocker Its very unportable but its supposed to make a true value 0xFFFFFFFF and a false value 0x00000000. This happens because test1 is assumed to be signed and 32 bits. Shifting the 1 all the way to the highest position and then shifting it back fills it with ones because the computer is doing a signed shift. This is not equivalent to (test & 1)
  • Lee Daniel Crocker
    Lee Daniel Crocker almost 11 years
    Then that's just (-(test & 1)). Big shifts just seem wasteful.
  • FDinoff
    FDinoff almost 11 years
    @LeeDanielCrocker That would turn 1 into 0xFFFFFFFE and 0 into 0xFFFFFFFF. These aren't the same. Also the test with & 1 is pointless since test is assumed to be 0 or 1 according to the question
  • Lee Daniel Crocker
    Lee Daniel Crocker almost 11 years
    Um, no, look again. (test & 1) evaluates to either 0 or 1, then the negative sign makes it 0 or -1, which is 0xFFFFFFFF. If we already know that it's 0 or 1, so much the better, then we just want -test.
  • FDinoff
    FDinoff almost 11 years
    @LeeDanielCrocker Woops I saw ~. But I guess that would be sufficient. But I'm not sure if the OP want a minus sign.