二元法及M元法求快速冪模

冪模運算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)

算法描述:

c1

for  iL-1 downto 0

do

{

    cc^2 mod N

    if e(i)=1

    then cc×m mod N

}

return(c)

如果將模N乘法運算與模N平方運算的計算複雜性的量級看做是相同的,則其計算複雜性爲O(log2 e)次模N乘法運算。

二、M元法描述

二元法是以二進制表示法爲基礎,所謂M元法,就是將e用M進制表示出來,再按照二元法計算方法進行冪模計算。下面對三元法算法進行描述。

算法描述:

c1

for  iL-1 downto 0

do

{

    cc^3 mod N

    if e(i)=1

    then cc×m mod N

    if e(i)=2

    then cc×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;
}

 

四、運行結果

 

 

五、常用求快速冪模或快速冪方法

 

 

在之前,我們先來了解一個公式:(a*b)%p=((a%p)*(b%p))%p ,那麼形如a^b(mod p)求冪模就是b個a相乘求模,如此問題就會變得簡單。下面直接上代碼:
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;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章