文章出處:http://blog.csdn.net/lsldd/article/details/5506933
參考文章來源:Reait Home(http://www.reait.com/blog.html)
轉載請註明,謝謝合作。
求a^b%c(這就是著名的RSA公鑰的加密方法),當a,b很大時,直接求解這個問題不太可能
代碼如下:
- int modexp_simple(int a,int b,int n)
- {
- int ret = 1;
- while (b--)
- {
- ret = a * ret % n;
- }
- return ret;
- }
可以把b按二進制展開爲:b = p(n)*2^n + p(n-1)*2^(n-1) +…+ p(1)*2 + p(0)
其中p(i) (0<=i<=n)爲 0 或 1
這樣 a^b = a^ (p(n)*2^n + p(n-1)*2^(n-1) +...+ p(1)*2 + p(0))
= a^(p(n)*2^n) * a^(p(n-1)*2^(n-1)) *...* a^(p(1)*2) * a^p(0)
對於p(i)=0的情況, a^(p(i) * 2^(i-1) ) = a^0 = 1,不用處理
我們要考慮的僅僅是p(i)=1的情況
化簡:a^(2^i) = a^(2^(i-1) * 2) = ( a^( p(i) * 2^(i-1) ) )^2
(這裏很重要!!具體請參閱秦九韶算法:http://baike.baidu.com/view/1431260.htm)
當然由算法1的結論,我們加上取模運算:
a^(2^i)%c = ( (a^(2^(i-1))%c) * a^(2^(i-1))) %c
於是再把所有滿足p(i)=1的a^(2^i)%c按照算法1乘起來再%c就是結果, 即二進制掃描從最高位一直掃描到最低位
實例代碼:遞歸
- //計算a^bmodn
- int modexp_recursion(int a,int b,int n)
- {
- int t = 1;
- if (b == 0)
- return 1;
- if (b == 1)
- return a%n;
- t = modexp_recursion(a, b>>1, n);
- t = t*t % n;
- if (b&0x1)
- {
- t = t*a % n;
- }
- return t;
- }
實例代碼2:非遞歸優化
- #include <iostream>
- using namespace std;
- //計算a^bmodn
- int modexp(int a,int b,int n)
- {
- int ret=1;
- int tmp=a;
- while(b)
- {
- //基數存在
- if(b&0x1) ret=ret*tmp%n;
- tmp=tmp*tmp%n;
- b>>=1;
- }
- return ret;
- }
- int main()
- {
- cout<<modexp(2,10,3)<<endl;
- return 0;
- }
原文:http://kmplayer.javaeye.com/blog/601578