Advertisement
ijontichy

findprimes.c

Sep 29th, 2013
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.77 KB | None | 0 0
  1. #include <math.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <string.h>
  6.  
  7. #define ARGLEN  10
  8. #define PRIMESIZE sizeof(uint64_t)
  9.  
  10. static uint64_t * primes_found = NULL;
  11. static uint64_t   prime_count  = 0;
  12.  
  13. /*  
  14.  *   findPrimes(maxPrime, maxCount)
  15.  *
  16.  *  Finds all primes up to either maxPrime, or finds as many primes as
  17.  *  maxCount, whichever is reached first. 0 in one means "not a factor".
  18.  *  0 in both is disallowed, and returns -1.
  19.  *
  20.  *  Upon normal completion, it will return the amount of primes that
  21.  *  have been found in all executions.
  22.  *
  23.  */
  24.  
  25. uint64_t findPrimes(uint64_t maxPrime, uint64_t maxCount)
  26. {
  27.     if (maxPrime == 0 && maxCount == 0) { return -1; }
  28.  
  29.     char primeCond = maxPrime != 0;
  30.     char countCond = maxCount != 0;
  31.  
  32.     if (primes_found == NULL)
  33.     {
  34.         primes_found = malloc(PRIMESIZE);
  35.         primes_found[0] = 2;
  36.         prime_count     = 1;
  37.     }
  38.  
  39.     // If we've already calculated past maxPrime, we're done here
  40.    
  41.     uint64_t prime = primes_found[prime_count-1] + 1;
  42.  
  43.     long double maxTestNum_f;
  44.     uint32_t    maxTestNum_i;
  45.  
  46.     uint64_t    curIndex;
  47.     uint64_t    curPrime;
  48.     uint8_t     isPrime;
  49.  
  50.     long double divResult_f;
  51.     uint64_t    divResult_i;
  52.  
  53.     while (1)
  54.     {
  55.         if (primeCond && maxPrime <= prime)       { break; }
  56.         if (countCond && maxCount <= prime_count) { break; }
  57.  
  58.         // No number has a prime factor larger than the square root of it
  59.         maxTestNum_f = sqrtl((long double)prime);
  60.         maxTestNum_i = (uint32_t)maxTestNum_f;
  61.  
  62.         isPrime = 1;
  63.  
  64.         // Test against all previous primes
  65.        
  66.         for (curIndex = 0; curIndex < prime_count; curIndex++)
  67.         {
  68.             curPrime = primes_found[curIndex];
  69.             if (curPrime > maxTestNum_i) { break; }
  70.  
  71.             divResult_f = (long double)prime / (long double)curPrime;
  72.             divResult_i = prime / curPrime;
  73.  
  74.             if (divResult_f == (long double)divResult_i)
  75.             {
  76.                 isPrime = 0;
  77.                 break;
  78.             }
  79.         }
  80.  
  81.         if (isPrime)
  82.         {
  83.             // Extend by one prime
  84.             primes_found = realloc(primes_found, PRIMESIZE * (++prime_count));
  85.             primes_found[prime_count - 1] = prime;
  86.         }
  87.  
  88.         prime++;
  89.     }
  90.  
  91.     return prime_count;
  92. }
  93.  
  94. /*   nthPrime(index)
  95.  *
  96.  *  Finds the nth prime, assuming it's been calculated. If it hasn't
  97.  *  been calculated, return 0.
  98.  *
  99.  *  For reference: nthPrime(1) = 2, nthPrime(2) = 3, nthPrime(3) = 5
  100.  *
  101.  */
  102.  
  103. uint64_t nthPrime(uint64_t index)
  104. {
  105.     if (--index >= prime_count) { return 0; }
  106.     return primes_found[index];
  107. }
  108.  
  109.  
  110. int main(void)
  111. {
  112.     uint64_t gotoPrime = 10001;
  113.  
  114.     printf("Found %lu primes\n", findPrimes(0, gotoPrime));
  115.     printf("Prime %lu is %lu\n", gotoPrime, nthPrime(gotoPrime));
  116.  
  117.     return 0;
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement