埃拉托斯特尼筛法

埃拉托斯特尼筛法（，），简称-{zh-cn:埃氏筛; zh-tw:埃氏筛; zh-hk:爱氏筛}-，是一种用来质数的筛法，得名于古希腊数学家埃拉托斯特尼。其基本步骤是从最小的质数2开始，将该质数的所有倍数标记成合数，而下一个尚未被标记的最小自然数3即是下一个质数。如此重复这一过程，将各个质数的倍数标记为合数并找出下一个质数，最终便可找出一定范围内所有质数。
埃拉托斯特尼筛法可能在埃拉托斯特尼的时代之前就已经为人所知，并记载于另一位古希腊数学家尼科马库斯的《》中，尽管该著作中的这一筛法是从3开始，从奇数中依次筛去奇数的倍数，而非从自然数中筛去质数的倍数。
运用与示例.
埃拉托斯特尼筛法通过不断地标记当前质数的所有倍数为合数，从而取得最小的未标记整数为下一个质数。不过，在实际使用此筛法寻找一个范围内的质数时，不需要检查范围内所有整数，也不需要对每个质数都标记其所有的倍数。
若要找出25以内的所有质数，使用如上述改进过的埃拉托斯特尼筛法的具体过程如下：
由此得到25内的质数为2，3，5，7，11，13，17，19，23。
以上的算法可用以下-{zh-cn:伪代码;zh-tw:虚拟码;}-表示：
-{zh-cn:
 输入：整数"n" &gt; 1
 设"A"为布尔值矩阵，下标是2至"n"的整数，
 初始时全部设成true。
 for "i" = 2, 3, 4, ..., 不超过：
 if "A"["i"]为true：
 for "j" = "i2", "i2+i", "i2+2i", "i2+3i", ..., 不超过"n"：
 "A"["j"] := false
 输出：使"A"["i"]为true的所有"i"。;zh-tw:
 输入：整数"n" &gt; 1
 设"A"为布尔值阵列，指标是2至"n"的整数，
 初始时全部设成true。
 for "i" = 2, 3, 4, ..., 不超过：
 if "A"["i"]为true：
 for "j" = "i2", "i2+i", "i2+2i", "i2+3i", ..., 不超过"n"：
 "A"["j"] := false
 输出：使"A"["i"]为true的所有"i"。;}-
埃拉托斯特尼筛法的时间复杂度为formula_16；相比之下，若是通过对范围内每个整数进行试除法来找出范围内的质数，则其时间复杂度为formula_17。
代码.
Python 3.6-3.10.
def eratosthenes(n):
 is_prime = [True] * (n + 1)
 for i in range(2, int(n ** 0.5) + 1):
 if is_prime[i]:
 for j in range(i * i, n + 1, i):
 is_prime[j] = False
 return [x for x in range(2, n + 1) if is_prime[x]]
print(eratosthenes(120))
C语言.
int prime[100005];
bool is_prime[1000005];
int eratosthenes(int n) {
 int p = 0;
 for (int i = 0; i &lt;= n; i++) {
 is_prime[i] = true;
 is_prime[0] = is_prime[1] = 0;
 for (int i = 2; i &lt;= n; i++) {
 if (is_prime[i]) {
 prime[p++] = i;
 if (1ll * i * i &lt;= n) {
 for (int j = i * i; j &lt;= n; j += i) {
 is_prime[j] = 0;
 return p;
C语言新版
/* N: positive integer
 verbose: 1 -- print all prime numbers &lt; N, 0 -- no print
 return total number of prime numbers &lt; N. 
 return -1 when there is not enough memory.
int eratosthenesSieve(unsigned long long int N, int verbose) {
 // prime numbers are positive, better to use largest unsiged integer
 unsigned long long int i, j, total; // total: number of prime numbers &lt; N
 _Bool *a = malloc(sizeof(_Bool) * N);
 if (a == NULL) {
 printf("No enough memory.\n");
 return -1;
 
 /* a[i] equals 1: i is prime number.
 a[i] equals 0: i is not prime number.
 From beginning, set i as prime number. Later filter out non-prime numbers
 for (i = 2; i &lt; N; i++) {
 a[i] = 1; 
 // mark multiples(&lt;N) of i as non-prime numbers
 for (i = 2; i &lt; N; i++) {
 if (a[i]) { // a[i] is prime number at this point
 for (j = i; j &lt; (N / i) + 1; j++) {
 /* mark all multiple of 2 * 2, 2 * 3, as non-prime numbers;
 do the same for 3,4,5... 2*3 is filter out when i is 2
 so when i is 3, we only start at 3 * 3
 a[i * j] = 0;
 // count total. print prime numbers &lt; N if needed.
 total = 0;
 for (i = 2; i &lt; N; i++) {
 if (a[i]) { // i is prime number
 if (verbose) {
 printf("%llu\n", i);
 total += 1;
 return total;
int main() {
 unsigned long long int a1 = 0, a2 = 0, N = 10000000;
 a1 = eratosthenesSieve(N, 1); // print the prime numbers
 printf("Total of prime numbers less than %llu is : %llu\n", N, a1);
 a2 = eratosthenesSieve(N, 0); // not print the prime numbers
 printf("Total of prime numbers less than %llu is : %llu\n", N, a2);
 return 0;
C++.
auto eratosthenes(int upperbound) {
 std::vector&lt;bool&gt; flag(upperbound + 1, true);
 flag[0] = flag[1] = false; //exclude 0 and 1
 for (int i = 2; i * i &lt;= upperbound; ++i) {
 if (flag[i]) {
 for (int j = i * i; j &lt;= upperbound; j += i)
 flag[j] = false;
 return flag;
R.
eratosthenes &lt;- function(n) {
 if (n == 1) return(NULL)
 if (n == 2 | n == 3) return(2:n)
 numbers &lt;- 2:n
 primes &lt;- rep(TRUE, n-1)
 for (i in 2:floor(sqrt(n))) {
 if (primes[i-1]) {
 for (j in seq(i * i, n, i))
 primes[j-1] &lt;- FALSE
 return(numbers[primes])
JavaScript.
const countPrimes = function (n) {
 const isPrime = new Array(n).fill(true);
 for (let i = 2; i &lt;= Math.sqrt(n); i++) {
 if (isPrime[i]) {
 for (let j = i * i; j &lt;= n; j += i) {
 isPrime[j] = false;
 let count = 0;
 for (let i = 2; i &lt; n; i++) {
 if (isPrime[i]) {
 count++;
 return count;