[英]Bitwise AND and order of operations in C/C++
我目前正在剖析ol'Doom引擎源代码,并遇到了一条有趣的话题:
counter = (++counter)&(MAX_VALUE-1);
看起来好像是在不超过一定数量的情况下增加计数器的方法,但是我花了很多时间在脑海中进行按位运算,所以我拨出了一个快速的控制台项目来尝试这一点,瞧瞧,它工作得很漂亮。 我推断出上述方法比if()语句更有效,尤其是在代码快速执行(例如,在实时游戏的性能至关重要的循环)内执行的情况下。 我要弄清楚的是编译器用来执行此行的操作顺序。 如果将增量“ ++”运算符放在“计数器”之后,它将始终保持为零。 它仅在将增量用作前缀(“ ++ counter”)时才有效,但是即使使用笔和纸将其写出,我仍然会得到按位AND运算的任意结果,而不是递增的计数器。 似乎按位运算已计算,然后执行了增量,但是我很困惑为什么会出什么主意?
虽然括号的优先级高于运算符++
或按位AND
(运算符&
),但右侧没有定义的序列点 。 因此,您的代码表现出未定义的行为。
如果您删除运算符++
,则打算这样做是
(counter + 1)&(MAX_VALUE-1);
如果您认为MAX_VALUE
为32
则二进制中的MAX_VALUE-1
为
11111
因此,如果您的值大于该值并使用&
,则将清除第5位(从右侧开始)的任何左位
0000011111 // assume this is MAX_VALUE - 1
1100110110 // assume this is counter + 1
__________
0000010110
其结果将是true
,如果任何的位小于或等于MAX_VALUE - 1
是1
。
公式
counter = (++counter)&(MAX_VALUE-1);
具有不确定的行为,请参阅CoryKramer的答案。
公式
counter = (counter + 1)&(MAX_VALUE - 1);
仅对等于2的幂的MAX_VALUE有效,只有这样MAX_VALUE - 1
二进制形式才有这种形式:
000...000111...111
当此类值用于AND运算时,它将“截断”另一个值的高位,并具有在另一个值达到MAX_VALUE时回绕的效果。
我认为普通的模运算在现代硬件上一样快,并且没有上面提到的限制:
counter = (counter + 1)%MAX_VALUE;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.