Thursday, January 6, 2011

Prime Number Generator

The function sieveOfAtkin() generates all primes numbers up to (less than) the integer PRIMES_UPTO.

For an explanation of Sieves of Atkin method, see here. Also see Sieve of Eratosthenes of which Sieve of Atkins is an optimized version.

#include <stdio.h>
#include <math.h>

#define PRIMES_UPTO     100

int list[PRIMES_UPTO+1]={0,0,1,1},n;
int primes[PRIMES_UPTO] ;

/* flip() and clean() are supporting routines called by sieveOfAtkin()
*/
int flip(void)
{
     if (list[n]==1) list[n]=0;
     else list[n]=1;
     return 0;
}

int clean(int n, int upto)
{
     int k,l=n*n,i;
     for (i=2,k=l;k<=upto;i++,k=i*l) list[k]=0;
     return 0;
}

/* Generates prime numbers upto the integer specified by PRIMES_UPTO.
    Stores the result in the array primes[] and returns index of the
    last prime number in the sequence.
*/
int sieveOfAtkin(void)
{
     int i, j, x, y, d_limit;

     d_limit=(int)(sqrt((float) PRIMES_UPTO));

     for (i=5;i<=PRIMES_UPTO;i++) list[i]=0;

     for (x=1;x<=d_limit;x++) {
         for (y=1;y<=d_limit;y++) {
             n=4*(x*x)+(y*y);
             if (n <= PRIMES_UPTO && (n % 12 == 1 || n % 12 == 5)) flip();

             n=3*(x*x)+(y*y);
             if (n <= PRIMES_UPTO && n % 12 == 7) flip();

             n=3*(x*x)-(y*y);
             if (x>y && n <= PRIMES_UPTO && n % 12 == 11) flip();
         }
     }

     for (n=5;n<=d_limit;n++) {
         if (list[n]) clean(n,PRIMES_UPTO);
     }

     for (i=2, j=0;i<=PRIMES_UPTO;i++) {
         if (list[i]) primes[j++] = i ;
     }

     return j-1 ;
}

int main()
{
     int i, k ;

     printf("Prime numbers between 0 and %d:\n", PRIMES_UPTO) ;
     k = sieveOfAtkin() ;
     for (i=0; i<=k; i++)
          printf("%d\n", primes[i]) ;

     return 0;
}

No comments:

Post a Comment

Followers