使用按位运算

时间:2013-10-14 03:34:21

标签: c optimization bit-manipulation conditional-statements

  • 你经常使用按位操作“hacks”来做某种事情 优化?在什么样的情况下它真的有用?

示例:而不是使用if:

if (data[c] >= 128) //in a loop
    sum += data[c];
你写道:

int t = (data[c] - 128) >> 31;
sum += ~t & data[c];

当然,假设它针对这种特定情况做了相同的预期结果。

  • 值得吗?我发现它不可读。你多久遇到一次 这个?

注意:我在选择的答案中看到了此代码:Why is processing a sorted array faster than an unsorted array?

3 个答案:

答案 0 :(得分:2)

虽然该代码是展示正在发生的事情的绝佳方式,但我通常不会使用这样的代码。如果必须快速,通常会有更快的解决方案,例如在x86上使用SSE或在ARM上使用NEON。如果没有这些可用,当然,我会使用它,只要它有帮助并且是必要的。

顺便说一下,我解释它的工作原理in this answer

像Skylion一样,我经常使用的一件事就是弄清楚一个数字是否是2的幂。想一想你是怎么做的......然后看看:(x & (x - 1)) == 0 && x != 0

我想,第一次看到它时很棘手,但是一旦你习惯它,它就会比任何不使用bitmath的替代方案简单得多。它起作用,因为从数字中减去1表示借位从数字的最右端开始并贯穿所有零,然后在第一个1处停止,变为零。然后用原始对该数字进行AND运算,使最右边的1为零。两个人的权力只有一个1,它消失,留下零。除了零之外,所有其他数字将至少剩下一个1,这是一种特殊情况。一个常见的变体不测试零,并且可以将其视为2的幂或者知道零不会发生。

同样,还有其他一些你可以轻易用bitmath做的事情,但没有那么容易。正如他们所说,使用正确的工具来完成工作。有时候,bitmath是正确的工具。

答案 1 :(得分:1)

有几种情况下使用此类黑客可能很有用。例如,他们可以删除一些Java虚拟机“优化”,例如分支预测器。我发现它们在少数情况下只有一次有用。主要是乘以-1。如果你在一个庞大的数组中做了数百次,那么简单地翻转第一位比实际多数更有效。我使用它的另一个例子是知道一个数字是2的幂(因为它很容易用二进制来计算。)基本上,当你想作弊时,比特黑客很有用。这是人类的比喻。如果你有数字列表,你需要知道它们是否大于29,你可以自动知道第一个数字是否大于3,然后整个数字大于30,反之亦然。按位运算只允许您执行类似的二进制作弊。

答案 2 :(得分:1)

按位操作非常有用,教授。 Knuth给他们写了一本书:http://www.amazon.com/The-Computer-Programming-Volume-Fascicle/dp/0321580508

仅举几个最简单的:int乘法和除以2的幂(使用左右移位),mod相对于2的幂,掩蔽等等。使用按位操作时,请确保提供有关正在进行的操作的充分注释。

但是,您的示例data[c]>128不适用于IMO,请保持这种方式。 但是如果你想计算data[c] % 128,那么data[c] & 0x7f要快得多(其中&代表按位AND)。