如何在没有(if / else)运算符的情况下将新值写入单个位

时间:2013-10-07 00:13:36

标签: c++ bit

我知道我可以通过以下方式设置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语句,而只使用二进制和移位运算符吗?

2 个答案:

答案 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的方法更好,除非优化器将它们全部优化为相同。