Question

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)

Was it helpful?

Solution

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)

OTHER TIPS

#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;
}

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.

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?

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

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top