最大公约数

大家都知道求最大公约数用Euclid辗转相除法,下面是辗转相除法的代码

int gcd(int n,int m)
{
    return m ? gcd(m, n%m) : n;
}

然而求余是相对较大的开销,尤其是对大数.减法操作开销小.

注意到 (n, m) = (n-m, m), 可以用减法代替求余.可是减法迭代太慢.下面的方法可以兼顾两者.

1. 若n和m均为偶数,则(n, m) = 2*(n/2, m/2).

2. 若n为偶数,m为奇数,则(n, m) = (n/2, m).

3. 若n和m均为奇数,则(n, m) = (n, n-m).

所以,可如下写代码.

int gcd(int n,int m)
{
    if (n & 1)
    {
        if (m & 1)
            return n > m ? gcd(m, n-m) : gcd(n, m-n);
        else
            return gcd(n, m>>1);
    }
    else
    {
        if (m & 1)
            return gcd(n>>1, m);
        else
            return 2 * gcd(n>>1, m>>1);
    }
}

posted on 2012-09-20 21:05  赛欧拉  阅读(108)  评论(0)    收藏  举报