It took me a fast routime for small prime numbers (up to several billions). Natural aglorithm - sieve of Eratosthenes. There are its good realizations, but as part of a large and complex projects. Including them in my own program is not easy. Much easier to write my own version.
Only odd numbers are stored in a sieve, one bit for each. Therefore, N bytes is sufficient for prime numbers up to 16*N+1. To store all primes up to 1 million requires 63K bytes. 1G bytes enough for primes till 16 billions.
The package consists of two files:
Eratosthenes.h - header,
Eratosthenes.cpp - realization.
The header:
typedef __int64 INT64; // For Visual C++, change this definition for other compilers void Sieve_fill(INT64 maxN); // fill sieve for primes till maxN void Sieve_free(); // free memory INT64 Sieve_Size(); // return size in BYTES! INT64 Sieve_maxN(); // return maximal N bool Sieve_isPrime( INT64 n); // is prime(n)? int Sieve_save(char *fname); // returns error code int Sieve_load(char *fname); // returns error codeAll prime numbers up to 4 billion are received for 72 sec. (AMD Athlon II X2 240, 2.8 GHz). The same with the replacement of __int64 to unsigned is done for 52 seconds., The difference is small, not worth trying. On the Intel Atom 1.66 GHz processor the same calculation takes 163 seconds (instead of 72).
Time to fill a sieve on the AMD Athlon II X2 240, 2.8 GHz
N max | 106 | 107 | 224 | 108 | 228 | 229 | 109 | 231 | 232 | 233 | 234 |
---|---|---|---|---|---|---|---|---|---|---|---|
time, sec | 0.056 | 0.064 | 0.11 | 1.3 | 3.9 | 8.3 | 16.2 | 37 | 72 | 155 | 326 |
Here the main, working function of primality test:
bool Sieve_isPrime( INT64 n) // is prime(n)? { INT64 y = (n>>1)-1; unsigned x8 = (unsigned)(y>>3); if( x8>=size ) return true; unsigned x3 = (unsigned)(y &7); return (v[x8]&(1<0? 1 : 0; }
Usage:
#include "Eratosthenes.h" ... Sieve_fill(1000000); // create list of primes till one mill. ... if( Sieve_isPrime(700001) ) {...} // check primularity ... Sieve_free();Configure the package to different processors and compilers is reduced to an adjustment line in the header file:
typedef __int64 INT64; // For Visual C++, change this definition for other compilersIt should indicate the name of the type 64-bit integers.
If the requested size is too large, a table isn't created, more accurately, created a table of zero size.
If requested on primality test the number exceeds the sizes of the table, it is considered as composite, the error doesn't occur. So check in advance the maximum number for verification:
INT64 Sieve_maxN();