Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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 ?

share|improve this question
3  
Why do you want to? – Pubby 13 hours ago
Are you allowed to use not !? – FDinoff 13 hours ago
+ is not a bitwise operator. – Oli Charlesworth 13 hours ago
1  
What's type of test? – kotlomoy 13 hours ago
1  
@noufal: Thanks, but you still haven't addressed the very first comment, above. What is the motivation for this requirement? Is it branch-avoidance, an intellectual exercise, homework, or something else? – Marcelo Cantos 13 hours ago
show 7 more comments

closed as too localized by Oli Charlesworth, Jens Gustedt, Stony, nvoigt, Ɓukasz Niemier 3 hours ago

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, see the FAQ.

2 Answers

up vote 1 down vote accepted

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|improve this answer
Why the wasteful and unportable ((test << 31) >> 31) instead of (test & 1) ? – Lee Daniel Crocker 13 hours ago
@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) – FDinoff 12 hours ago
Then that's just (-(test & 1)). Big shifts just seem wasteful. – Lee Daniel Crocker 12 hours ago
@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 – FDinoff 12 hours ago
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. – Lee Daniel Crocker 12 hours ago
show 1 more comment

Does it have be bitwise operators? What about:

output = (    test1) * a +
         (1 - test1) * ((    test2) * b +
                        (1 - test2) * ((    test3) * c +
                                       (1 - test3) * d));

Another possibility, only using bit-wise operators, is this:

switch ((test1 << 2) | (test2 << 1) | test3) {
    case 0: output = d; break;
    case 1: output = c; break;
    case 2:
    case 3: output = b; break;
    case 4:
    case 5:
    case 6:
    case 7: output = a; break;
}

If you're lucky (and if it speeds things up), the compiler will implement the switch using a jump table.

You really have to question, though, whether these tricksy solutions offer enough of a speed bump (if they do) to justify the additional complexity. I assume you're trying to avoid branching.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.