用于大整数的GCD算法

时间:2012-05-21 21:36:56

标签: algorithm complexity-theory double-precision greatest-common-divisor computation

我正在寻找有关快速GCD计算算法的信息。 特别是,我想看看它的实现。

对我来说最有趣的是: - Lehmer GCD算法, - 加速GCD算法, - k-ary算法, - 带有FFT的Knuth-Schonhage。 我完全没有关于加速GCD算法的信息,我刚看到一些文章,其中提到它是中等输入(~1000位)上最有效和最快速的gcd计算方法

从理论的角度来看,我们很难理解它们。 任何人都可以分享代码(最好是在c ++上)与列表中任何算法\部分的实现或分享任何经验。我将非常感谢任何信息,评论,建议,地方。我有一个使用大整数的类,但我没有方法可以使用它。当然,除了欧几里德和二进制gcd算法,我现在看起来很清楚;这没有问题。 我想在最后得到的主要内容:实现lehmer gcd的代码。 (从列表中可以更容易)

2 个答案:

答案 0 :(得分:6)

Knuth在计算机编程艺术,第2卷,第4.5.2节中详细探讨了GCD。 Knuth将算法E作为欧几里德的原始方法,算法A作为欧几里德算法的现代版本,算法B作为二进制方法,算法L作为莱默方法,以及算法X中的扩展欧几里德算法。我描述(带代码) )我博客上的original Euclidean algorithmmodern Euclidean algorithmbinary algorithmextended Euclidean algorithm

This paper很好地描述了Schönhage算法的几个版本,包括代码。

答案 1 :(得分:1)

非常感谢您的回答user448810。这个二进制算法对我来说非常适合并且速度很快。我将其转换为非递归形式以节省内存和递归调用。 这是我的longnum lib的实现,为与标准运算符/函数

不同的行添加了一些rems
longnum gcd(longnum x,longnum y)
    {
    x.sig=+1; x.integer(); // x=abs(int(x))
    y.sig=+1; y.integer(); // y=abs(int(y))
    longnum z; int x0,y0,sh=0;
    for (;;)
        {
        if (x.iszero()) { z=y; break; } // if (!x) ...
        if (y.iszero()) { z=x; break; } // if (!y) ...
        x0=x.a[_longnum_a1]&1; // x0=x&1
        y0=y.a[_longnum_a1]&1; // y0=y&1
        if ((!x0)&&(!y0)) { x>>=1; y>>=1; sh++; continue; }
        if (!x0) { x>>=1; continue; }
        if (!y0) { y>>=1; continue; }
        if (x<y) y-=x;
        else     x-=y;
        }
    return (z<<sh);
    }