幂模运算m^e (mod N),当m或者e很大时,其计算复杂度将非常高。因此希望有其他更快的计算方法,下面介绍二元法及M元法快速的运算方法。
一、二元法描述
在幂模运算中,比较常用的一种方法是二元法(也称为平方乘法),就是先将指数e以二进制表示法表示出来,即:
e=e0+e1×2+e2×2^2+.....+e(L-1)×2^(L-1)
于是运算过程为:
m^e(mod N)=(...(m^(e(L-1))^2×m^(e(L-2))^2...m^e1)^2×m^e0 (mod N)
算法描述:
c←1
for i←L-1 downto 0
do
{
c←c^2 mod N
if e(i)=1
then c←c×m mod N
}
return(c)
如果将模N乘法运算与模N平方运算的计算复杂性的量级看做是相同的,则其计算复杂性为O(log2 e)次模N乘法运算。
二、M元法描述
二元法是以二进制表示法为基础,所谓M元法,就是将e用M进制表示出来,再按照二元法计算方法进行幂模计算。下面对三元法算法进行描述。
算法描述:
c←1
for i←L-1 downto 0
do
{
c←c^3 mod N
if e(i)=1
then c←c×m mod N
if e(i)=2
then c←c×m^2 mod N
}
return(c)
三、C++实现二元法求快速幂模
#include<iostream>
using namespace std;
/*
递归实现十进制转换成二进制存储于e
*/
void conversion_binary(int a,string &e){
int b;
b=a%2;
if(a>=2){
conversion_binary(a/2,e);//递归
}
e+=b+'0';
}
int main()
{
string e;
long long c=1; //防止溢出
int i;
int m,a,N;
cout<<mod_fast(1268,24,154265)<<endl;
cout<<"形如m^a(mod N),请输入m,a,N"<<endl;
cin>>m>>a>>N;
conversion_binary(a,e);//转换二进制
i=e.size();
cout<<e<<endl;
//二元法主体
for(int j=0;j<i;j++){
c=(c*c)%N;
if(e[j]-'0'==1)//当e[j]=1时计算
c=(c*m)%N;
}
cout<<c<<endl;
return 0;
}
四、运行结果
五、常用求快速幂模或快速幂方法
long long mod_fast(long long a,int b,long long p)
{
long long aa=a,t=1;
while(b!=0)
{
if(b&1)//是b和1做二进制的且运算 即看b的最后边那一位是不是1,是1的话 返回1 否则返回0
{
t=(t%p)*(aa%p)%p;
}
aa=(aa%p)*(aa%p)%p;
b=b/2;//aa平方模
}
return t%p;
}
int main()
{
cout<<mod_fast(1268,24,154265)<<endl;
return 0;
}