[英]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
,如果保证唯一可能的值为0
和32
并且希望将这些值分别转换为0
和1
,那么此操作就足够了:
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.