一、Stein算法過程及其簡單證明
1.一般步驟:
s1:當兩數均為偶數時將其同時除以2至至少一數為奇數為止,記錄除掉的所有公因數2的乘積k;
s2:如果仍有一數為偶數,連續除以2直至該數為奇數為止;
s3:用更相減損法(輾轉相減法),即GCD(a,b)=GCD(a-b,b),或輾轉相除法求出兩奇數的最大公約數d;
s4:原來兩數的最大公約數即為d*k;
2.簡單證明:
s1:即為求出兩數為2的冪次方的最大公因數k;
s2:當化簡后兩數一奇一偶時,顯然奇數是不含偶數因子的,那么另一化簡后偶數的所有偶數因子都不可能為原來兩數的最大公因數的因子;
s3:求出原來兩數不為2的冪次方的最大公因數d;
s4:最大公因數即為2的冪次方的最大公因數k乘以不為2的冪次方的最大公因數d;
3.Stein算法的優點:
歐幾里得算法在處理較小數字時優勢是明顯的,但對於大整數時,高精度的整除和取余運算就顯得非常復雜,所以Stein算法的優點就在於只需要進行移位(位運算)和減法操作,處理高精度GCD問題時相對簡便;
4.相關位運算符的簡單介紹:
(1)按位與(&):
a&x為對數a的二進制形式的取位操作,即去a二進制形式的第x位。這里有一個重要應用就是a&1可以用於判斷數a的奇偶性,即a末位為0即為偶數,末位為1即為奇數。
(2)異或運算(^):
具體介紹參考之前的隨筆:http://www.cnblogs.com/COLIN-LIGHTNING/p/8298554.html;
應用為交換兩數:a=b,b=a,a^=b即完成了兩數交換。
(3)按位左移(<<):
a<<=x即為使a乘以2的x次冪,原理是讓a的二進制形式左移x位;應用為對與2的冪次方相乘使運算更快更方便;
(4)按位右移(>>):
a>>=x即為使a除以2的x次冪,原理是讓a的二進制形式右移x位;應用為對與2的冪次方相除使運算更快更方便;
5.一般代碼:
(1)遞歸形式:
int stein(int a,int b){
if(a<b) a^=b,b^=a,a^=b; //交換,使a為較大數;
if(b==0)return a; //當相減為零,即兩數相等時,gcd=a;
if((!(a&1))&&(!(b&1))) return stein(a>>1,b>>1)<<1; //s1,注意最后的左移,在遞歸返回過程中將2因子乘上;
else if((a&1)&&(!(b&1)))return stein(a,b>>1); //s2;
else if((!(a&1))&&(b&1))return stein(a>>1,b);
else return stein(a-b,b); //s3;
}
(2)迭代形式:
int stein(int a,int b){
int k=1;
while((!(a&1))&&(!(b&1))){ //s1;
k<<=1; //用k記錄全部公因子2的乘積 ;
a>>=1;
b>>=1;
}
while(!(a&1))a>>=1; //s2;
while(!(b&1))b>>=1;
if(a<b) a^=b,b^=a,a^=b; //交換,使a為較大數;
while(a!=b){ //s3;
a-=b;
if(a<b) a^=b,b^=a,a^=b;
}
return k*a;
}