Stein算法(求两个数最大公约数)

20 篇文章 1 订阅
15 篇文章 1 订阅
欧几里德算法是计算两个数最大公约数的传统算法,他无论从理论还是从效率上都是很好的。但是他有一个致命的缺陷,这个缺陷只有在大素数时才会显现出来。

考虑现在的硬件平台,一般整数最多也就是64位,对于这样的整数,计算两个数之间的模是很简单的。对于字长为32位的平台,计算两个不超过32位的整数的模,只需要一个指令周期,而计算64位以下的整数模,也不过几个周期而已。但是对于更大的素数,这样的计算过程就不得不由用户来设计,为了计算两个超过64位的整数的模,用户也许不得不采用类似于多位数除法手算过程中的试商法,这个过程不但复杂,而且消耗了很多CPU时间。对于现代密码算法,要求计算128位以上的素数的情况比比皆是,设计这样的程序迫切希望能够抛弃除法和取模。

Stein算法由J. Stein 1961年提出,这个方法也是计算两个数的最大公约数。和欧几里德算法 算法不同的是,Stein算法只有整数的移位和加减法,这对于程序设计者是一个福音。

为了说明Stein算法的正确性,首先必须注意到以下结论:

gcd(a,a) = a,也就是一个数和他自身的公约数是其自身
gcd(ka,kb) = k gcd(a,b),也就是最大公约数运算和倍乘运算可以交换,特殊的,当k=2时,说明两个偶数的最大公约数必然能被2整除

C++/实现
// c++stein 算法
int gcd(int a,int b){
    if(ab{
        int temp = a;
        a = b;
        b=temp;
    }
    if(0==b)//the base case
        return a;
    if(a%2==0 && b%2 ==0)//a and b are even
        return 2*gcd(a/2,b/2);
    if ( a%2 == 0)// only a is even
        return gcd(a/2,b);
    if ( b%2==0 )// only b is even
        return gcd(a,b/2);

    return gcd((a+b)/2,(a-b)/2);// a and b are odd

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是个数最大公约数C语言,Stein算法的代码及解释: ```c #include <stdio.h> int gcd(int a, int b) { if (a == 0) return b; if (b == 0) return a; int k = 0; while ((a & 1) == 0 && (b & 1) == 0) { a >>= 1; b >>= 1; k++; } while ((a & 1) == 0) { a >>= 1; } while (b != 0) { while ((b & 1) == 0) { b >>= 1; } if (a > b) { int temp = a; a = b; b = temp; } b -= a; } return a << k; } int main() { int a, b; printf("请输入个整数:"); scanf("%d %d", &a, &b); printf("它们的最大公约数是:%d\n", gcd(a, b)); return 0; } ``` 解释: 这是使用 Stein 算法个数最大公约数的 C 语言代码。Stein 算法是一种比较高效的算法,它可以在不使用除和模运算的情况下个数最大公约数。 首先,我们需要判断个数是否为 0,如果其中一个数为 0,那么另一个数就是它们的最大公约数。 然后,我们需要将个数都除以 2 直到它们都变成奇数。这样做的原因是,如果个数都是偶数,那么它们的最大公约数也一定是偶数,因此我们可以将它们都除以 2,直到它们都变成奇数。 接下来,我们使用辗转相减个数最大公约数。具体来说,我们先将其中较小的数减去较大的数,然后不断重复这个过程,直到其中一个数变成 0。这样做的原因是,如果个数最大公约数是 d,那么它们一定可以表示成 d * x 和 d * y 的形式,其中 x 和 y 都是整数。因此,我们可以将其中较大的数减去较小的数,直到它们相等,然后再将它们中的一个数减去另一个数,直到其中一个数变成 0。这样做的结果是,我们得到了个数最大公约数倍,因此最后需要将它乘以 2 的 k 次方,其中 k 是我们在一开始将个数都除以 2 的次数。 最后,我们可以将这个算法封装成一个函数,然后在主函数中调用它来个数最大公约数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值