问题描述
clang和GCC具有int __builtin_ctz(unsigned)
函数。这将以整数形式计算尾随零。 Wikipedia article on this family of functions提到可以使用__builtin_ctz
加速二进制GCD算法,但我不知道如何。
二进制GCD的sample implementation看起来像这样:
unsigned int gcd(unsigned int u,unsigned int v)
{
// simple cases (termination)
if (u == v)
return u;
if (u == 0)
return v;
if (v == 0)
return u;
// look for factors of 2
if (~u & 1) // u is even
if (v & 1) // v is odd
return gcd(u >> 1,v);
else // both u and v are even
return gcd(u >> 1,v >> 1) << 1;
if (~v & 1) // u is odd,v is even
return gcd(u,v >> 1);
// reduce larger argument
if (u > v)
return gcd(u - v,v);
return gcd(v - u,u);
}
我怀疑我可以如下使用__builtin_ctz
:
constexpr unsigned int gcd(unsigned int u,unsigned int v)
{
// simplified first three ifs
if (u == v || u == 0 || v == 0)
return u | v;
unsigned ushift = __builtin_ctz(u);
u >>= ushift;
unsigned vshift = __builtin_ctz(v);
v >>= vshift;
// Note sure if max is the right approach here.
// In the if-else block you can see both arguments being rshifted
// and the result being leftshifted only once.
// I expected to recreate this behavior using max.
unsigned maxshift = std::max(ushift,vshift);
// The only case which was not handled in the if-else block before was
// the odd/odd case.
// We can detect this case using the maximum shift.
if (maxshift != 0) {
return gcd(u,v) << maxshift;
}
return (u > v) ? gcd(u - v,v) : gcd(v - u,u);
}
int main() {
constexpr unsigned result = gcd(5,3);
return result;
}
不幸的是,这还行不通。程序结果为4,应为1。那么,我在做什么错呢?如何在这里正确使用__builtin_ctz
? See my code so far on GodBolt。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)