【发布时间】:2015-06-19 02:30:43
【问题描述】:
我遇到了一个 C sn-p,它使用按位逻辑执行漂亮的模算术运算:
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 中,如果有在线参考解释这一点,欢迎您提供它,但不是完整的答案。我希望看到从底部到顶部的表达式以清晰的步骤过渡...
评论 This 链接建议当 b 是 2 的幂时这可能适用。 这个other 链接解释了按位 & 不会分布在加法上。
假设在表达式...&(-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
【问题讨论】:
-
你说 "c is ...大于 a+b" 但在第二个表达式中,c=(a+b)-x 其中 x 为正数。 (我假设
a>=0,b>0) -
@axiac 是的,但你添加了
(((a+b)%b)?b:0)。第一部分相当于从a+b中删除(a+b)/b的余数,如果余数不为零,则第二部分加回b... -
糟糕,我的括号不匹配。现在我注意到它是 - ((a+b)%b )
-
实验表明,
a = 5、b = 3(结果为 5 , 既不大于 8 也不能被 5 整除。 -
实验表明,
a = 5、b = 2的断言也不成立,即使在这种情况下b是 2 的幂(结果是 6,不大于7).
标签: c bitwise-and modular-arithmetic