Eliminating IF statement using bitwise operators

僤鯓⒐⒋嵵緔 提交于 2021-01-27 17:25:03

问题


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)


回答1:


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)



回答2:


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



回答3:


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.




回答4:


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?




回答5:


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




回答6:


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



回答7:


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.



来源:https://stackoverflow.com/questions/21995355/eliminating-if-statement-using-bitwise-operators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!