问题
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