求最大公約數(GCD)的兩種算法


之前一直只知道歐幾里得輾轉相除法,今天學習了一下另外一種、在處理大數時更優秀的算法——Stein

特此記載

 

1.歐幾里得(Euclid)算法

又稱輾轉相除法,依據定理gcd(a,b)=gcd(b,a%b)

實現過程演示: sample:gcd(15,10)=gcd(10,5)=gcd(5,0)=5

C語言實現:

1 int Euclid_GCD(int a, int b)
2 {
3     return b?Euclid_GCD(b, a%b):a;
4 }

 

2.Stein 算法

一般實際應用中的整數很少會超過64位(當然現在已經允許128位了),對於這樣的整數,計算兩個數之間的模是很簡單的。對於字長為32位的平台,計算兩個不超過32位的整數的模,只需要一個指令周期,而計算64位以下的整數模,也不過幾個周期而已。但是對於更大的素數,這樣的計算過程就不得不由用戶來設計,為了計算兩個超過 64位的整數的模,用戶也許不得不采用類似於多位數除法手算過程中的試商法,這個過程不但復雜,而且消耗了很多CPU時間。對於現代密碼算法,要求計算 128位以上的素數的情況比比皆是,設計這樣的程序迫切希望能夠拋棄除法和取模。

依據定理:

gcd(a,a)=a,也就是一個數和其自身的公約數仍是其自身。
gcd(ka,kb)=k*gcd(a,b),也就是 最大公約數運算和倍乘運算可以交換。特殊地,當k=2時,說明兩個偶數的 最大公約數必然能被2整除。
當k與b互為質數,gcd(ka,b)=gcd(a,b),也就是約掉兩個數中只有其中一個含有的因子不影響 最大公約數。特殊地, 當k=2時,說明計算一個偶數和一個奇數的最大公約數時,可以先將偶數除以2
 
C語言實現:
 1 int Stein_GCD(int x, int y)
 2 {
 3     if (x == 0) return y;
 4     if (y == 0) return x;
 5     if (x % 2 == 0 && y % 2 == 0)
 6         return 2 * Stein_GCD(x >> 1, y >> 1);
 7     else if (x % 2 == 0)
 8         return Stein_GCD(x >> 1, y);
 9     else if (y % 2 == 0)
10         return Stein_GCD(x, y >> 1);
11     else
12         return Stein_GCD(min(x, y), fabs(x - y));
13 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM