繁体   English   中英

C / C ++中的按位与和操作顺序

[英]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_VALUE32则二进制中的MAX_VALUE-1

11111

因此,如果您的值大于该值并使用& ,则将清除第5位(从右侧开始)的任何左位

0000011111   // assume this is MAX_VALUE - 1 
1100110110   // assume this is counter + 1
__________
0000010110

其结果将是true ,如果任何的位小于或等于MAX_VALUE - 11

公式

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM