my_mpz_powm_ui.cc

Go to the documentation of this file.
00001 
00007 void my_mpz_powm_ui(mpz_t a, unsigned int n, const mpz_t m)
00008 {
00009   // berechnet a=a^n mod m, n>1, n (möglichst) prim,
00010   // dies ist eine alternative Vorgehensweise zur binären Version, die
00011   // für Primzahlen ein wenig schneller sein sollte...
00012   // Idee dahinter:
00013   // Wenn in n viele Bits gesetzt sind, müssen auch viele Zweierpotenzen
00014   // in der Exponentation kumuliert werden. Dann wird es in vielen
00015   // Fällen billiger sein, den Exponenten n anderweitig zusammenzusetzen.
00016   // Eine Möglichkeit besteht darin, n-1 in Faktoren zu zerlegen, die
00017   // ihrerseits wenig "Bitoverhead" haben.
00018 
00019   if (n<127) { mpz_powm_ui(a,a,n,m); return; } 
00020 
00021   register unsigned int h = n;
00022   register int b = 0;
00023   while (h) { b+=(h&1) ? 3 : -4; h>>=1; } // #gesetzte Bits bestimmen
00024   //cout << "b= " << b << endl;
00025 
00026   if (b<0)
00027    {
00028      //cout << "---> " << n << endl; 
00029      mpz_powm_ui(a,a,n,m);
00030      return;
00031    }
00032 
00033   //cout << "-> " << n << endl; 
00034   mpz_t r;
00035   mpz_init_set(r,a);
00036   n--;
00037 
00038   h=0; while ((n&1)==0) { n>>=1; h++; }
00039   if (h) mpz_powm_ui(r,r,1<<h,m);
00040   while (n%129==0) { n/=129; mpz_powm_ui(r,r,129,m); }
00041   while (n%65==0) { n/=65; mpz_powm_ui(r,r,65,m); }
00042   while (n%33==0) { n/=33; mpz_powm_ui(r,r,33,m); }
00043   while (n%17==0) { n/=17; mpz_powm_ui(r,r,17,m); }
00044   while (n%9==0) { n/=9; mpz_powm_ui(r,r,9,m); }
00045   while (n%5==0) { n/=5; mpz_powm_ui(r,r,5,m); }
00046   while (n%3==0) { n/=3; mpz_powm_ui(r,r,3,m); }
00047 //  while (n%7==0) { n/=7; mpz_powm_ui(r,r,7,m); }
00048   while (n%11==0) { n/=11; mpz_powm_ui(r,r,11,m); }
00049   while (n%13==0) { n/=13; mpz_powm_ui(r,r,13,m); }
00050   while (n%19==0) { n/=19; mpz_powm_ui(r,r,19,m); }
00051   //while (n%23==0) { n/=19; mpz_powm_ui(r,r,23,m); }
00052   //while (n%29==0) { n/=29; mpz_powm_ui(r,r,29,m); }
00053   if (n>1) mpz_powm_ui(r,r,n,m);
00054   mpz_mul(a,a,r); mpz_mod(a,a,m);
00055   mpz_clear(r);
00056 }

Generated on Wed Nov 7 23:29:25 2007 for Qsieve by  doxygen 1.5.4