2

I am trying to eliminate an IF statement whereby if I receive the number 32 I would like a '1', but any other number I would like a '0'.

32 is 0010 0000 so I thought about XOR-ing my input number with 1101 1111. Therefore if I get the number 32 I end up with 1111 1111.

Now is there any way of AND-ing the individual bits (1111 1111), because if one of my XOR results is a 0, it means my final AND-ed value is 0, otherwise its a 1?

EDIT: Using GCC, not Intel compiler (because I know there are a lot of intrinsic functions there)

4
  • what do you mean that its still a conditional? that's not a conditional? there would be no branch instructions generated? (so i think what you just said would be great!?) Commented Feb 24, 2014 at 18:02
  • == is a condition. Even if you explicitly have an if statement, the compiler could optimize it away, the only way to tell is to look at the generated assembly. Commented Feb 24, 2014 at 18:04
  • 1
    Perhaps.. (x & 32) >> (5 + (x & ~32)). First part only leaves 1 bit when x = 32, and second part shifts it out if any other bit is 1. Quite baroque :P Commented Feb 24, 2014 at 18:05
  • 3
    @epx: (x & 32) && !(x & ~32) Commented Feb 24, 2014 at 18:08

7 Answers 7

9

The expression

  !(x ^ 32)

will do the trick for you if you insist.

That will always work in C, and will also work in almost all C++ settings. Technically in C++ it evaluates to a boolean which in almost all circumstances will work like 0 or 1, but if you want a technically correct C++ answer:

  (0 | !(x^32))

or:

(int)!(x ^ 32)

or with the more modern / verbose C++ casting

static_cast<int>(x ^ 32)
Sign up to request clarification or add additional context in comments.

13 Comments

Is it guaranteed to be 1 if true? Normally it is, but I don't think it is guaranteed.
@epx, Yes, true is guaranteed to be 1 per [conv.prom].
How does this actually work? I dont see how negating the XOR would work? Say the result of my XOR was 1111 0011, why does "!(1111 0011)" = 0?
The only way of producing 0 bits as a result of XOR is if the two input bits are the same. Therefore the only way of producing an all zero bit answer is if the two input integers are the same. Therefore x^32 will be zero if an only if x=32. Therefore !(x^32) will be 1 if and only if x=32, else it will be zero. 1 is guaranteed to be equal to true and 0 false in response to the other commenter.
!z = 0 unless z = 0 in which case !z = 1.
|
0
#include <iostream>

int fun(int x)
{
   //   32 == 0010 0000
   // 0xDF == 1101 1111
   return (((x ^ 32) & 0xDF) == 0);
}

int main()
{
   std::cout << "fun(32): " << fun(32) << std::endl;
   std::cout << "fun(16): " << fun(16) << std::endl;
   std::cout << "fun(18): " << fun(18) << std::endl;
   std::cout << "fun(48): " << fun(48) << std::endl;
}

Comments

0

In my experience optimizing actual low level code on real hardware with tools like oprofile, convoluted branchless code like '(x & 32) && !(x & ~32)', '!(x ^ 32)' or '(x & 32) >> (5 + (x & ~32))' compiles to many more instructions than 'if (x==32) blah else foo;'

The simple if statement can usually be implemented with a conditional move with no branch misprediction penalty.

1 Comment

But the only possible purpose of eliminating the if is to obfuscate anyway.
0

If you do an exclusive OR (i.e, XOR) with the same number you always get 0. So why don't you XOR with 32 and negate the outcome?

Comments

0

It seems like the most obvious would be just int result = static_cast<int>(x==32).

Comments

0

For an integer x, if you are guaranteed the only possible values are 0 and 32 and would like to transform these values to 0 and 1 respectively, then this operation will suffice:

x >>= 5; // 0x00000000 goes to 0x00000000, 0x00000020 goes to 0x00000001

Comments

0

Take x and divide by 32 (shift right 5 bits) and then mask off all the bits other than the first bit:

unsigned int r = (x>>5)&1;

For any number with the 6th bit set (Decimal 32) the first bit (Decimal 1) will now be set. The other bits need to be masked off, otherwise a number like 96 (32 + 64) would produce a result of 3.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.