Advertisement
Guest User

PI Generation from Random Numbers

a guest
Apr 19th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.48 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <math.h>
  5. #include <pthread.h>
  6.  
  7. long long int perThreadOperations = 0;
  8.  
  9. unsigned short gcd(unsigned short u, unsigned short v) {
  10.     unsigned short shift = 0;
  11.  
  12.     if (u == 0) return v;
  13.     if (v == 0) return u;
  14.     while (((u | v) & 1) == 0) {
  15.         shift++;
  16.         u >>= 1;
  17.         v >>= 1;
  18.     }
  19.  
  20.     while ((u & 1) == 0)
  21.         u >>= 1;
  22.  
  23.     do {
  24.         while ((v & 1) == 0)
  25.             v >>= 1;
  26.  
  27.         if (u > v) {
  28.             unsigned short t = v; v = u; u = t;
  29.         }
  30.        
  31.         v -= u;
  32.     } while (v != 0);
  33.  
  34.     return u << shift;
  35. }
  36.  
  37. void *genPairs(void * arg) {
  38.    
  39.     long long amount = *(long long int *)arg;
  40.     long long coprimeCount = 0;
  41.  
  42.     srandom(time(NULL));
  43.  
  44.     int mngflFrct = amount*0.01;
  45.  
  46.     for(long long int a = 0 ; a < amount; ++a) {
  47.         if(a % mngflFrct*5) printf("\r%5.2f%%", 100.0*((float) a/ (float) amount));
  48.         unsigned short rand1 = random(), rand2 = random();
  49.        
  50.         if(gcd(rand1,rand2) == 1)
  51.             coprimeCount++;
  52.     }
  53.  
  54.     pthread_exit((void *)coprimeCount);
  55. }
  56.  
  57. int main(int argc, char **argv) {
  58.     if(argc != 3) {
  59.         printf("Usage: RandomPi <Thread Count> <Pair Ammount>");
  60.         return -4;
  61.     }
  62.  
  63.     long long pairCount = atoll(argv[2]);
  64.     char threadCount = atoi(argv[1]);
  65.  
  66.     printf("Threads: %d\r\n", threadCount);
  67.    
  68.     pthread_t threads[threadCount];
  69.  
  70.     long long mainCoprimeCounter = 0;
  71.  
  72.     //TODO - Implement a better way to split load between threads
  73.  
  74.     perThreadOperations = pairCount/threadCount;
  75.     printf("Operations per single thread: %lld\r\n", perThreadOperations);
  76.  
  77.     for(int a = 0 ; a < threadCount ; ++a) {
  78.         pthread_create(&threads[a], NULL, genPairs, &perThreadOperations);
  79.     }
  80.  
  81.     for(int a = 0 ; a < threadCount ; ++a) {
  82.         void *coprimeCount;
  83.         pthread_join(threads[a], &coprimeCount);
  84.         mainCoprimeCounter+=(long long)coprimeCount;
  85.     }
  86.  
  87.     long long cofactors = perThreadOperations * threadCount - mainCoprimeCounter;
  88.  
  89.     printf("Statistics:\r\n\tCoprime pairs: %lld\r\n\tCofactor pairs: %lld\n\tPairs altogether: %lld\r\n", mainCoprimeCounter, cofactors, mainCoprimeCounter + cofactors);
  90.  
  91.     long double piApprox;
  92.    
  93.     if(mainCoprimeCounter != 0 && cofactors != 0) {
  94.         long double coprimeShare = (long double)mainCoprimeCounter/((long double)pairCount);
  95.         piApprox = sqrtl((long double)6/coprimeShare);
  96.        
  97.         printf("\r\n\tPi Approximation: %.15Lf", piApprox);
  98.     } else {
  99.         printf("One of the critical variables is zero!\r\nApproximating PI impossible.");
  100.     }
  101. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement