快速计算乘方的算法:
如计算2^13,则传统做法需要进行12次乘法。
- //计算n^p
- unsigned power(unsigned n,unsigned p)
- {
- for(int i = 0; i < p; i++)
- n *= n;
- return n;
- }
优化如下:
把2*2的结果保存起来:4*4*4*4*4*4*2
再把4*4的结果保存起来:16*16*16*2
一共5次运算,分别是2*2、4*4和16*16*16*2
- unsigned int power(unsigned int n, unsigned int p)
- {
- // 计算n的p次方
- unsigned int tmp = 1;
- while (p > 1)
- {
- // 判断p是否奇数,偶数的最低位必为0
- if (( p & 1 )!=0)
- {
- tmp *= n; // 若p为奇数,则把“剩下的”乘起来
- }
- n *= n;
- p >>= 1;
- }
- return n * tmp; // 最后把主体和“剩下的”乘起来作为结果
- }
Montgomery 快速幂模算法:
- unsigned int Montgomery(unsigned int n, unsigned int p, unsigned int m)
- {
- unsigned int r = n % m;
- unsigned int tmp = 1;
- while (p > 1)
- {
- if ((p & 1)!=0)
- {
- tmp = (tmp * r) % m;
- }
- r = (r * r) % m;
- p >>= 1;
- }
- return (r * tmp) % m;
- }