我知道我可以通过以下方式设置N:
VALUE |= 1 << N;
或通过以下方式清除N位:
VALUE &= ~(1 << N);
但是,“写入”(未设置或清除)位N的最有效方法是什么? 例如,我有一个功能:
__inline void writeBit(char &value, int N, bool state)
{
if(state)
value |= 1 << N;
else
value &= ~(1 << N);
}
我可以以某种方式摆脱if / else语句,而只使用二进制和移位运算符吗?
答案 0 :(得分:2)
Bit Hacks页面建议使用以下公式:
value ^= (-state ^ value) & (1 << N);
state
的声明需要从bool
更改为int
。
这个技巧适用于具有负数的二进制补码表示的计算机,因为一元减号-state
将状态1
更改为由1组成的数字,并保持零不变。
超标量CPU的替代方案如下所示:
value = (value & ~(1 << N)) | (-state & (1 << N));
答案 1 :(得分:1)
我会选择简单的解决方案:
inline void writeBit(char &value, int N, bool state)
{
value &= ~(1 << N); // Unconditional clear. We don't care about old value.
value |= char(state) << N; // Unconditional set to intended value.
}
由于这是如此清晰和普遍,任何体面的优化器都会认识到意图并使用最佳解决方案。根据{{1}},这两条指令中的任何一条都是无用的,但也是无害的。这比你的代码中的分支更好。
我希望这比dasblinkenlight的方法更好,除非优化器将它们全部优化为相同。