我遇到了一个 C 代码片段,它使用按位逻辑执行漂亮的模数运算:
int a,b,c;
c = (a + b - 1) & (- b) +b;
c 的值是 b 大于 a+b 的最小倍数(根据 John Bollinger 的回答进行了编辑)。我试图向自己解释这是如何工作的(我对模算术和 & 操作之间的关系有一个模糊的理解),但缺乏洞察力。另一方面,看起来我可以将其表达为
c = (a+b) - ((a+b)%b) + (((a+b)%b)?b:0)
这个表达很容易理解。此外,模块化的外观和?操作表明各个部分可以表示为按位逻辑,并以某种方式简化为顶部的表达式。但是怎么做?如果有人想试一试,我会把它留作练习(这不是家庭作业)。实现不需要在 C 中,如果有一个在线参考解释了这一点,欢迎您提供它,但不会是一个完整的答案。我想以清晰的步骤看到从底部到顶部表达式的过渡......
评论 此链接表明当 b 是 2 的幂时这可能适用。此其他链接解释了按位 & 不分布在加法上。
假设在表达式...&(-b)
中 ,(-b)
可以替换为(nums(int)-b)
,其中nums(int)
是表示中可能的整数的总数。
随意指定您最喜欢的编译器/C 版本。
示例代码:
int a,b,c;
int alow, ahigh;
b = 16;
alow = 8;
ahigh = 20;
printf("a+b c lcm(a+b,b) + ?b \n");
for (a=alow;a<ahigh;a++) {
c = ((a+b-1) & (-b)) +b;
printf("%5d %5d %5d \n",a+b, c, (a+b) - ((a+b)%b) + (((a+b)%b)?b:0) );
}
样本输出:
a+b c lcm(a+b,b) + ?b
24 32 32
25 32 32
26 32 32
27 32 32
28 32 32
29 32 32
30 32 32
31 32 32
32 32 32
33 48 48
34 48 48
35 48 48