设置或重置给定位而不分支

时间:2013-07-23 07:25:44

标签: c bit-manipulation

在一次采访中,他们问我,你如何设置或重置一下?这是一个非常简单的问题,我回答了这个问题。

之后他们问我,做without branching。我不知道什么是分支。 我寻找那个,我来到这里 http://graphics.stanford.edu/~seander/bithacks.html

但仍未获得分支和非分支的概念。 请解释Branching

2 个答案:

答案 0 :(得分:11)

分支意味着cpu执行的指令包含条件跳转。一个或两个选择。这可能意味着iffor - 循环,while - 循环,switch?:或根据布尔值做出决定的内容。< / p>

人们经常忘记的一类分支也是短路布尔运算符,并且可能(但不一定在所有CPU上)评估为真值的东西,因此int foo; ...; foo = !foo;将成为某些CPU的分支,但是不是全部(不是在x86上)。

所以设置一下:

i |= (1 << bit);

重置一下:

i &= ~(1 << bit);

稍微切换:

i ^= (1 << bit);

没有分支机构。我实际上不知道如何使这个如此复杂以至于必须使用分支。

有人可能想要担心分支的原因是分支预测。 See this question and answer for an excellent explanation of why it matters.

答案 1 :(得分:8)

可能是他们想让你展示如何编写没有分支的通用设置/重置片段......

这可以通过

完成
value = (value & ~(1 << bit)) | (bitval << bit);

其中bit是位位置,bitval为1表示设置,0表示复位。

以下内容更为一般:

value = (value & ~(k1 << bit)) ^ (k2 << bit);

实现了几个操作:

  • k1=0k2=0不执行任何操作
  • k1=0k2=1切换位
  • k1=1k2=0清除位
  • k1=1k2=1设置位

更常见的是

value = (value & a) ^ x;

您可以决定通过

同时更改value的几个位
  • aj=0xj=0→将它们设为0
  • aj=0xj=1→将它们设为1
  • aj=1xj=0→保持不变
  • aj=1xj=1→翻转

取决于预先计算的常量axajxj是常量中第j位的值。)

例如

value = (value & 0x0F) ^ 0x3C;

只需一次操作

- leave untouched bit 0 and 1
- flip bits 2 and 3
- set to 1 bits 4 and 5
- set to 0 all other bits