如何使用__builtin_ctz加速二进制GCD算法?

问题描述

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_ctzSee my code so far on GodBolt

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)