Modulo hatványozás


Ez afüggvény kiszámítja ab mod c értékét.

A számítás a következő módon megy végbe:
ab kiszámítható lenne úgy, hogy a-t megszorozzuk a-val b-szer. Ha azonban b nagy, a számítás ilyen módon millió évekig tartana, még a világ leggyorsabb mikroprocesszorával is.

Ennél gyorsabb némileg, ha kiszámítjuk az a, a2, a4, ..., a2n, ... értékeket. Legyen b bináris megjelenítése b0, b1, ... , bn, ... és bn a b n-edik bitje. a^b értéke a következő egyenlettel számítható ki:

ab=f[b_1*a] * f[b_2a2] * ... f[b_n*a2n] ...

ahol f[x] egy olyan függvény, amely minden egész számra identitás, kivéve a nullát, ahol f[0]=1. Más szavakkal a szorzatba csak azokat a tagokat vesszük be, ahol bi nem nulla bit. A képlet végén levő három pont végtelen szorzást jelentene, de egy idő után b-nek csupa nulla bitje van, hiszen b véges.

Ezzel az eljárással a számítás időigénye arányos a b bitjeinek a számával és nem b nagyságával.

Mivel minket nem érdekel a^b értéke, csak a^b mod c ezért minden egyes szorzás után az eredményt helyettesíthetjük a c-vel adott osztási maradékával. Ezzel annyi memóriahelyet és időt tudunk spórolni, hogy a számítás elvégezhető.

Number Power(Number a, Number b, Number c){
 register Number ActPower,Ac,result,re;
 register int bLength,bit,i;
 register u8 ActB;
a^0 mod c mindig 1
 if( (bLength = Length(b)) == 0 )
 return CreateNumber(1L);
 ActPower = DupNumber(a);
0^b mod c mindig nulla
 if( !Length(ActPower) )return ActPower;
 result = CreateNumber(1L);
/* b miden egyes digitjén */
 for( i = 0 ; i digit[i];
/* a digit minden bitjére */
 for( bit = 0 ; bit <8 ; bit++ ){ if( actb&1 ){/* ha az aktuális bit egy */ re="<A" href="mult.htm">Multiply(result,ActPower);
 DisposeNumber(result);
 if( !re ){
 return (Number)0;
 }
 result = Remainder(re,c);
 DisposeNumber(re);
 if( !result ){
 return (Number)0;
 }
 }
 ActB >>= 1;
 Ac = Square(ActPower);
 if( Ac->n == -1 ){
 Ac->n = Ac->n;
 }
 DisposeNumber(ActPower);
 if( !Ac ){
 return (Number)0;
 }
 ActPower = Remainder(Ac,c);
 DisposeNumber(Ac);
 if( !ActPower ){
 return (Number)0;
 }
 }
 }
 DisposeNumber(ActPower);
 return result;
 }

Square

Ez egy makró, amely semmi más, mint egy szám önnmagával való szorzása.
#define Square(x) Multiply(x,x)

toc