简体   繁体   English

使用按位运算符消除IF语句

[英]Eliminating IF statement using bitwise operators

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'. 我试图消除一个IF语句,如果我收到数字32,我想要一个'1',但任何其他数字我想要'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. 32是0010 0000所以我考虑用1101 1111对我的输入数字进行异或。因此如果我得到数字32,我最终会得到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? 现在有没有任何方法可以对各个位进行AND运算(1111 1111),因为如果我的一个XOR结果为0,则表示我的最终AND-ed值为0,否则为1?

EDIT: Using GCC, not Intel compiler (because I know there are a lot of intrinsic functions there) 编辑:使用GCC,而不是英特尔编译器(因为我知道那里有很多内在函数)

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. 这将始终在C中工作,并且几乎可以在所有C ++设置中工作。 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: 从技术上讲,它在C ++中的计算结果为布尔值,在几乎所有情况下都可以像0或1那样工作,但如果你想要一个技术上正确的C ++答案:

  (0 | !(x^32))

or: 要么:

(int)!(x ^ 32)

or with the more modern / verbose C++ casting 或者使用更现代/更详细的C ++演员

static_cast<int>(x ^ 32)
#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;' 根据我的经验,使用oprofile,复杂的无分支代码(如'(x&32)&&!(x&~32)','!(x ^ 32)'或'(x&32)等工具优化实际硬件上的实际低级代码)>>(5 +(X〜32))”编译成许多比多个指令'如果(X == 32)等等其他FOO;'

The simple if statement can usually be implemented with a conditional move with no branch misprediction penalty. 简单的if语句通常可以通过没有分支错误预测惩罚的条件移动来实现。

如果你使用相同的数字进行异或(即异或),那么你总是得到0.那你为什么不用32与XOR结合并否定结果呢?

看起来最明显的只是int result = static_cast<int>(x==32)

对于整数x ,如果保证唯一可能的值为032并且希望将这些值分别转换为01 ,那么此操作就足够了:

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: 取x并除以32(右移5位),然后屏蔽除第一位以外的所有位:

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. 对于第6位设置(十进制32)的任何数字,现在将设置第一位(十进制1)。 The other bits need to be masked off, otherwise a number like 96 (32 + 64) would produce a result of 3. 其他位需要被屏蔽掉,否则像96(32 + 64)这样的数字会产生3的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM