/* Questo programma fa parte di una libreria messa a disposizione dei lettori del libro Alessandro Languasco & Alessandro Zaccagnini, Introduzione alla Crittografia, Ulrico Hoepli Editore, Milano, 2004. Crivello di Eratostene per la determinazione dei numeri primi "piccoli" Si veda il Paragrafo 6.3 del libro citato. */ #include #include /* Modificare il valore di queste due costanti in relazione alla quantità di memoria disponibile */ static const long MASSIMO = 500000; // crivello l'intervallo [1, 2 * MASSIMO] static const long RADICE = 1000; // radice quadrata troncata di "2 * MASSIMO + 1" /* Crivello di Eratostene "n_primi[]" è un array di `MASSIMO" booleani che rappresentano i numeri DISPARI da 1 a 2 * MASSIMO. La cella "i"-esima dell'array "n_primi[]" rappresenta l'intero dispari "2*i + 1". In questo modo si risparmiano le celle di memoria corrispondenti agli interi pari, al costo di qualche piccola complicazione di dettaglio. Questa funzione scrive i numeri primi trovati (uno per riga) nel file Primi.dat */ void eratostene() { FILE *fp; fp = fopen("Primi.dat", "w"); bool n_primi[MASSIMO] = {MASSIMO * false}; std::cout << "Crivello" << std::endl; // Crivello con i numeri dispari nell'intervallo [3, RADICE] for(long i = 3; i < RADICE; i += 2) // Si comincia da "i*i", al quale corriponde l'elemento // (i*i-1)/2 dell'array "n_primi[j]" for(long j = (i * i - 1) / 2; j < MASSIMO; j += i) n_primi[j] = true; std::cout << "Fine crivello. Inizio conteggio... " << std::endl; // 1 non è un numero primo n_primi[0] = true; // 2 è un numero primo, ma, poiché è pari, non viene determinato // in questa versione del crivello, e deve essere inserito nella // lista esplicitamente std::cout << " 2"; fprintf(fp, "2\n"); long count = 1; for(long i = 0; i < MASSIMO; ++i) if (!n_primi[i]) { ++count; std::cout << " " << 2 * i + 1; fprintf(fp, "%ld\n", 2*i+1); // Stampiamo sullo schermo 10 primi per riga if ((count % 10) == 0) std::cout << std::endl; } std::cout << std::endl << "Numero dei numeri primi trovati: "; std::cout << count << std::endl; fclose(fp); } int main() { eratostene(); }