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:
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
#define Square(x) Multiply(x,x)