之前一直只知道歐幾里得輾轉相除法,今天學習了一下另外一種、在處理大數時更優秀的算法——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,也就是一個數和其自身的公約數仍是其自身。
當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 }
