1

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

4

2 回答 2

2

Bit Hacks的页面建议使用以下公式:

value ^= (-state ^ value) & (1 << N);

声明state需要从更改boolint.

这个技巧适用于负数的二进制补码表示的计算机,因为一元减号-state将状态更改1为由 1 组成的数字,并且保持零不变。

超标量 CPU 的替代方案如下所示:

value = (value & ~(1 << N)) | (-state & (1 << N));
于 2013-10-07T00:19:54.033 回答
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. 
}

由于这是如此清晰和普遍,任何体面的优化器都会识别意图并使用最佳解决方案。这两个指令中的任何一个都将是无用的,这取决于state,但也是无害的。这比您在代码中拥有的分支更好。

我希望这比 dasblinkenlight 的任何一种方法都好,除非优化器将它们全部优化为相同。

于 2013-10-07T10:34:23.910 回答