【发布时间】:2020-10-07 01:34:00
【问题描述】:
static inline bool is_divisible(uint32_t n, uint64_t M) {
return n * M <= M - 1;
}
static uint64_t M3 = UINT64_C(0xFFFFFFFFFFFFFFFF) / 3 + 1;
....
uint8_t div3 = is_divisible(17, M3);
正如标题中提到的,这个函数可以判断n是否能被3整除。
我唯一知道的是M 与ceil((1<<64)/d) 相同,d 是 3。
有没有人打电话解释为什么is_divisible 工作?谢谢!
【问题讨论】:
-
这似乎依赖于整数溢出。我看不出这比使用简单的模运算符更好。
-
@paddy 除法运算对处理器来说代价高昂。乘法更便宜。
M3也可以在运行前被删除。 -
@Steven 是的,但是如果你把函数改成
return n % 3 == 0;,优化器无论如何都会把除法转换成乘法,所以不需要这段代码。 -
提示:找出
2*M3和3*M3是什么。然后将您的号码写为n=3*x+y,其中y是0、1或2。使用算术属性,确定n*M3可能是什么,以及何时小于M3-1。 -
确实使用这些优化通常hinders the good compilers from generating effective code。只需使用
M3 % 17并让编译器计算出来