Advertisement
Guest User

BBP Pi mod By ShuffleSource

a guest
Mar 14th, 2013
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.34 KB | None | 0 0
  1. /*  
  2.     This program implements the BBP algorithm to generate a few hexadecimal
  3.     digits beginning immediately after a given position id, or in other words
  4.     beginning at position id + 1.  On most systems using IEEE 64-bit floating-
  5.     point arithmetic, this code works correctly so long as d is less than
  6.     approximately 1.18 x 10^7.  If 80-bit arithmetic can be employed, this limit
  7.     is significantly higher.  Whatever arithmetic is used, results for a given
  8.     position id can be checked by repeating with id-1 or id+1, and verifying
  9.     that the hex digits perfectly overlap with an offset of one, except possibly
  10.     for a few trailing digits.  The resulting fractions are typically accurate
  11.     to at least 11 decimal digits, and to at least 9 hex digits.  
  12. */
  13.  
  14. /*  David H. Bailey     2006-09-08 */
  15. /* !!!MODIFIED BY BALÁZS KÓTI     2013-03-14!!! */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <math.h>
  21.  
  22. int main(int argc, char *argv[])
  23. {
  24.   if (argc >= 2)
  25.   {
  26.     //paraméterek
  27.     int szamjegyek = atoi(argv[1]);
  28.     int kezdo; //hanyadik rész?
  29.     int kiir;
  30.     switch (argc)
  31.     {
  32.       case 2:
  33.         kezdo = 1;
  34.         kiir = 1;
  35.       case 3:
  36.         kezdo = atoi(argv[2]);
  37.         kiir = 1;
  38.         break;
  39.       case 4:
  40.         kezdo = atoi(argv[2]);
  41.         kiir = atoi(argv[3]);
  42.         break;
  43.       default:
  44.         printf("hiba!\n");
  45.         return 0;
  46.         break;
  47.     }
  48.  
  49.     //csak 10-el osztható darab számot lehet generálni
  50.     if (szamjegyek%10 != 0)
  51.     {
  52.       printf("10-el osztható darab számjegyet lehet csak generálni!\n");
  53.       return 0;
  54.     }
  55.  
  56.     //fájlkezelés
  57.     char fileName[FILENAME_MAX];
  58.     sprintf(fileName, "PiGen_%d_%d.txt", szamjegyek, kezdo);
  59.     FILE *file;
  60.     file = fopen(fileName ,"a+");
  61.  
  62.     //számítás
  63.     double pid, s1, s2, s3, s4;
  64.     double sorozat (int m, int n);
  65.     void ihex (double x, int m, char c[]);
  66.     #define NHX 16
  67.     char chx[NHX];
  68.     float toredek,folyamat;
  69.     int kiirszamlalo = 0;
  70.     //
  71.     printf("====PiGen by Shuffle=====\n");
  72.     printf("Kezdo : %d, számjegyek: %d\n", kezdo, szamjegyek);
  73.     printf("Mentett fájl: %s\n", fileName );
  74.     if (kiir == 0)
  75.       printf("Kiíratás kikapcsolva!\n");
  76.     for(toredek=0;toredek<szamjegyek/10;toredek++)
  77.     {
  78.       int toredekMul = ((kezdo - 1) * szamjegyek) + (toredek * 10);
  79.       s1 = sorozat (1, toredekMul);
  80.       s2 = sorozat (4, toredekMul);
  81.       s3 = sorozat (5, toredekMul);
  82.       s4 = sorozat (6, toredekMul);
  83.       pid = 4. * s1 - 2. * s2 - s3 - s4;
  84.       pid = pid - (int) pid + 1.;
  85.       ihex (pid, NHX, chx);
  86.       fprintf(file, "%10.10s", chx );
  87.       //folyamat kiírása
  88.       if (kiir == 1 && kiirszamlalo == 20)
  89.       {
  90.         if (system("cls")) system("clear");
  91.         printf("====PiGen by Shuffle=====\n");
  92.         printf("Kezdo : %d, számjegyek: %d\n", kezdo, szamjegyek);
  93.         printf("Mentett fájl: %s\n", fileName );
  94.         folyamat = (toredek/(szamjegyek/10))*100;
  95.         printf("Gerenálás...%.2f\n",folyamat);
  96.         printf("Aktuális csonk: %10.10s\n",chx);
  97.         kiirszamlalo = 0;
  98.       }
  99.  
  100.       kiirszamlalo++;
  101.     }
  102.     printf("KÉSZ!\n");
  103.     fclose(file);
  104.     /* printf (" position = %i\n fraction = %.15f \n hex digits =  %10.10s\n",
  105.     toredek, pid, chx);*/
  106.   }
  107.   else
  108.     printf("Nincs megadva paraméter! Paraméterek: <számjegyek száma> <hanyadik rész> <kiíratás ki/be (0/1)> \n");
  109.   return 0;
  110. }
  111.  
  112. void ihex (double x, int nhx, char chx[])
  113.  
  114. /*  This returns, in chx, the first nhx hex digits of the fraction of x. */
  115.  
  116. {
  117.   int i;
  118.   double y;
  119.   char hx[] = "0123456789ABCDEF";
  120.  
  121.   y = fabs (x);
  122.  
  123.   for (i = 0; i < nhx; i++){
  124.     y = 16. * (y - floor (y));
  125.     chx[i] = hx[(int) y];
  126.   }
  127. }
  128.  
  129. double sorozat (int m, int id)
  130.  
  131. /*  This routine evaluates the sorozat  sum_k 16^(id-k)/(8*k+m)
  132.     using the modular exponentiation technique. */
  133.  
  134. {
  135.   int k;
  136.   double ak, eps, p, s, t;
  137.   double expm (double x, double y);
  138. #define eps 1e-17
  139.  
  140.   s = 0.;
  141.  
  142. /*  Sum the sorozat up to id. */
  143.  
  144.   for (k = 0; k < id; k++){
  145.     ak = 8 * k + m;
  146.     p = id - k;
  147.     t = expm (p, ak);
  148.     s = s + t / ak;
  149.     s = s - (int) s;
  150.   }
  151.  
  152. /*  Compute a few terms where k >= id. */
  153.  
  154.   for (k = id; k <= id + 100; k++){
  155.     ak = 8 * k + m;
  156.     t = pow (16., (double) (id - k)) / ak;
  157.     if (t < eps) break;
  158.     s = s + t;
  159.     s = s - (int) s;
  160.   }
  161.   return s;
  162. }
  163.  
  164. double expm (double p, double ak)
  165.  
  166. /*  expm = 16^p mod ak.  This routine uses the left-to-right binary
  167.     exponentiation scheme. */
  168.  
  169. {
  170.   int i, j;
  171.   double p1, pt, r;
  172. #define ntp 25
  173.   static double tp[ntp];
  174.   static int tp1 = 0;
  175.  
  176. /*  If this is the first call to expm, fill the power of two table tp. */
  177.  
  178.   if (tp1 == 0) {
  179.     tp1 = 1;
  180.     tp[0] = 1.;
  181.  
  182.     for (i = 1; i < ntp; i++) tp[i] = 2. * tp[i-1];
  183.   }
  184.  
  185.   if (ak == 1.) return 0.;
  186.  
  187. /*  Find the greatest power of two less than or equal to p. */
  188.  
  189.   for (i = 0; i < ntp; i++) if (tp[i] > p) break;
  190.  
  191.   pt = tp[i-1];
  192.   p1 = p;
  193.   r = 1.;
  194.  
  195. /*  Perform binary exponentiation algorithm modulo ak. */
  196.  
  197.   for (j = 1; j <= i; j++){
  198.     if (p1 >= pt){
  199.       r = 16. * r;
  200.       r = r - (int) (r / ak) * ak;
  201.       p1 = p1 - pt;
  202.     }
  203.     pt = 0.5 * pt;
  204.     if (pt >= 1.){
  205.       r = r * r;
  206.       r = r - (int) (r / ak) * ak;
  207.     }
  208.   }
  209.  
  210.   return r;
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement