Skip to main content
added 69 characters in body
Source Link
Dennis_E
  • 1.2k
  • 7
  • 10

For relatively small numbers, the best method is very likely the Sieve of Erathostenes.

Here's a method I wrote a few years ago that implements it. A useful thing to do is to use a BitArray; it will save a lot of space. It also skips even numbers to save even more space. I also made it return each number in sequence instead of returning a List.

Finding prime numbers up to int.MaxValue takes about 45 seconds (and uses +/- 130Mb of memory). Using 1 million as bound will be lightning fast, though. It can be done faster still, but the code would become more complex.

public static IEnumerable<int> Primes(int bound)
{
    if (bound < 2) yield break;
    //The first prime number is 2
    yield return 2;

    BitArray composite = new BitArray((bound - 1) / 2);
    int limit = ((int)(Math.Sqrt(bound)) - 1) / 2;
    for (int i = 0; i < limit; i++) {
        if (composite[i]) continue;
        //The first number not crossed out is prime
        int prime = 2 * i + 3;
        yield return prime;
        //cross out all multiples of this prime, starting at the prime squared
        for (int j = (prime * prime - 2) >> 1; j < composite.Count; j += prime) {
            composite[j] = true;
        }
    }
    //The remaining numbers not crossed out are also prime
    for (int i = limit; i < composite.Count; i++) {
        if (!composite[i]) yield return 2 * i + 3;
    }
}

For larger numbers, you need more advanced techniques. A popular one is the Miller-Rabin primality test.

For relatively small numbers, the best method is very likely the Sieve of Erathostenes.

Here's a method I wrote a few years ago that implements it. A useful thing to do is to use a BitArray; it will save a lot of space. It also skips even numbers to save even more space. I also made it return each number in sequence instead of returning a List.

Finding prime numbers up to int.MaxValue takes about 45 seconds (and uses +/- 130Mb of memory). Using 1 million as bound will be lightning fast, though.

public static IEnumerable<int> Primes(int bound)
{
    if (bound < 2) yield break;
    //The first prime number is 2
    yield return 2;

    BitArray composite = new BitArray((bound - 1) / 2);
    int limit = ((int)(Math.Sqrt(bound)) - 1) / 2;
    for (int i = 0; i < limit; i++) {
        if (composite[i]) continue;
        //The first number not crossed out is prime
        int prime = 2 * i + 3;
        yield return prime;
        //cross out all multiples of this prime, starting at the prime squared
        for (int j = (prime * prime - 2) >> 1; j < composite.Count; j += prime) {
            composite[j] = true;
        }
    }
    //The remaining numbers not crossed out are also prime
    for (int i = limit; i < composite.Count; i++) {
        if (!composite[i]) yield return 2 * i + 3;
    }
}

For larger numbers, you need more advanced techniques. A popular one is the Miller-Rabin primality test.

For relatively small numbers, the best method is very likely the Sieve of Erathostenes.

Here's a method I wrote a few years ago that implements it. A useful thing to do is to use a BitArray; it will save a lot of space. It also skips even numbers to save even more space. I also made it return each number in sequence instead of returning a List.

Finding prime numbers up to int.MaxValue takes about 45 seconds (and uses +/- 130Mb of memory). Using 1 million as bound will be lightning fast, though. It can be done faster still, but the code would become more complex.

public static IEnumerable<int> Primes(int bound)
{
    if (bound < 2) yield break;
    //The first prime number is 2
    yield return 2;

    BitArray composite = new BitArray((bound - 1) / 2);
    int limit = ((int)(Math.Sqrt(bound)) - 1) / 2;
    for (int i = 0; i < limit; i++) {
        if (composite[i]) continue;
        //The first number not crossed out is prime
        int prime = 2 * i + 3;
        yield return prime;
        //cross out all multiples of this prime, starting at the prime squared
        for (int j = (prime * prime - 2) >> 1; j < composite.Count; j += prime) {
            composite[j] = true;
        }
    }
    //The remaining numbers not crossed out are also prime
    for (int i = limit; i < composite.Count; i++) {
        if (!composite[i]) yield return 2 * i + 3;
    }
}

For larger numbers, you need more advanced techniques. A popular one is the Miller-Rabin primality test.

Source Link
Dennis_E
  • 1.2k
  • 7
  • 10

For relatively small numbers, the best method is very likely the Sieve of Erathostenes.

Here's a method I wrote a few years ago that implements it. A useful thing to do is to use a BitArray; it will save a lot of space. It also skips even numbers to save even more space. I also made it return each number in sequence instead of returning a List.

Finding prime numbers up to int.MaxValue takes about 45 seconds (and uses +/- 130Mb of memory). Using 1 million as bound will be lightning fast, though.

public static IEnumerable<int> Primes(int bound)
{
    if (bound < 2) yield break;
    //The first prime number is 2
    yield return 2;

    BitArray composite = new BitArray((bound - 1) / 2);
    int limit = ((int)(Math.Sqrt(bound)) - 1) / 2;
    for (int i = 0; i < limit; i++) {
        if (composite[i]) continue;
        //The first number not crossed out is prime
        int prime = 2 * i + 3;
        yield return prime;
        //cross out all multiples of this prime, starting at the prime squared
        for (int j = (prime * prime - 2) >> 1; j < composite.Count; j += prime) {
            composite[j] = true;
        }
    }
    //The remaining numbers not crossed out are also prime
    for (int i = limit; i < composite.Count; i++) {
        if (!composite[i]) yield return 2 * i + 3;
    }
}

For larger numbers, you need more advanced techniques. A popular one is the Miller-Rabin primality test.