As mentioned before use Sieve of Eratosthenes
- on my AMD 3.2 GHz Win7 x64 single threaded 32bit C++ (BDS2006) App:
[4929.114 ms] find primes <= 100000000 found 5761456 primes
- so it took almost 5 seconds to compute
- my implementation use single bit per any odd number so you need N/16 Bytes of memory
- for your 100 000 000 it is almost 6 MB which is OK I think
this is the source in C++:
//---------------------------------------------------------------------------
int primes_found=0;
void addprime(int p)
{
// here do the stuff you want to do with prime p=2,3,5,7,...
// I just count the primes found ...
primes_found++;
}
//---------------------------------------------------------------------------
void getprimes(int p) // compute all primes up to p
{
// sieves N/16 bytes
// ------------------------------
// 0 1 2 3 4 5 6 7 bit
// ------------------------------
// 1 3 5 7 9 11 13 15 +-> +2
// 17 19 21 23 25 27 29 31 |
// 33 35 37 39 41 43 45 47 V +16
// ------------------------------
int N=(p|15),M=(N>>4)+1; // store only odd values 1,3,5,7,... each bit ...
char *m=new char[M]; // m[i] -> is 1+i+i prime? (factors map)
int i,j,k;
// init sieves
m[0]=254; for (i=1;i<M;i++) m[i]=255;
for(i=3;i<=N;i+=2)
for(k=i+i,j=i+k;j<=N;j+=k)
m[j>>4]&=255-(1<<((j>>1)&7));
// compute primes
addprime(2);
for(i=1,j=i>>4;j<M;i+=16,j++)
{
k=m[j];
if (!k) continue;
if (int(k& 1)!=0) addprime(i );
if (int(k& 2)!=0) addprime(i+ 2);
if (int(k& 4)!=0) addprime(i+ 4);
if (int(k& 8)!=0) addprime(i+ 6);
if (int(k& 16)!=0) addprime(i+ 8);
if (int(k& 32)!=0) addprime(i+10);
if (int(k& 64)!=0) addprime(i+12);
if (int(k&128)!=0) addprime(i+14);
}
delete[] m;
}
//---------------------------------------------------------------------------
- you can use
#define addprime(prime) {...}
instead of function
- but in my compiler that is a bit slower (don know why)
usage:
getprimes(100000000);
[Notes]
- even this can be further optimized and speed-ed up (the init sieves part)
- but I am too lazy to try
- this is faster on my setup then N/2 Bytes version probably due to Caching
[edit1] init sieves by primes only
// init sieves
m[0]=254; for (i=1;i<M;i++) m[i]=255;
for(i=1;i<=N;) // here could be also sqrt(N) instead of N (or half the bits number)
{
int a=m[i>>4];
if (int(a& 1)!=0) for(k=i+i,j=i+k;j<=N;j+=k) m[j>>4]&=255-(1<<((j>>1)&7)); i+=2;
if (int(a& 2)!=0) for(k=i+i,j=i+k;j<=N;j+=k) m[j>>4]&=255-(1<<((j>>1)&7)); i+=2;
if (int(a& 4)!=0) for(k=i+i,j=i+k;j<=N;j+=k) m[j>>4]&=255-(1<<((j>>1)&7)); i+=2;
if (int(a& 8)!=0) for(k=i+i,j=i+k;j<=N;j+=k) m[j>>4]&=255-(1<<((j>>1)&7)); i+=2;
if (int(a& 16)!=0) for(k=i+i,j=i+k;j<=N;j+=k) m[j>>4]&=255-(1<<((j>>1)&7)); i+=2;
if (int(a& 32)!=0) for(k=i+i,j=i+k;j<=N;j+=k) m[j>>4]&=255-(1<<((j>>1)&7)); i+=2;
if (int(a& 64)!=0) for(k=i+i,j=i+k;j<=N;j+=k) m[j>>4]&=255-(1<<((j>>1)&7)); i+=2;
if (int(a&128)!=0) for(k=i+i,j=i+k;j<=N;j+=k) m[j>>4]&=255-(1<<((j>>1)&7)); i+=2;
}
[1520.160 ms] find primes <= 100000000 found 5761456 primes
- now it takes ~1.5 seconds
- I checked first 1000000 primes (up to 15485863) and the output is correct