问题
Does anyone happen to know of a C# Sieve of Atkin algorithm using BigInteger? From my understanding, this is the best known prime factorization algorithm currently in existence.
I currently have this function:
/// <summary>
/// Finds prime numbers using the Sieve of Atkins algorithm.
/// </summary>
/// <param name="max">The limit of the prime list.</param>
/// <returns>The list of prime numbers.</returns>
public List<int> FindPrimes(int max)
{
var isPrime = new bool[max + 1];
var sqrt = (int) Math.Sqrt(max);
Parallel.For(1, sqrt, x =>
{
var xx = x * x;
for (int y = 1; y <= sqrt; y++)
{
var yy = y * y;
var n = 4 * xx + yy;
if (n <= max && (n % 12 == 1 || n % 12 == 5))
isPrime[n] ^= true;
n = 3 * xx + yy;
if (n <= max && n % 12 == 7)
isPrime[n] ^= true;
n = 3 * xx - yy;
if (x > y && n <= max && n % 12 == 11)
isPrime[n] ^= true;
}
});
var primes = new List<int>() { 2, 3 };
for (int n = 5; n <= sqrt; n++)
{
if (isPrime[n])
{
primes.Add(n);
int nn = n * n;
for (int k = nn; k <= max; k += nn)
isPrime[k] = false;
}
}
for (int n = sqrt + 1; n <= max; n++)
if (isPrime[n])
primes.Add(n);
return primes;
}
But I would like to have a function signature that looks more like below so it can take in a single number to test and output true if the number is prime.
public bool IsPrime(BigInteger number) { ... }
回答1:
I think, by the nature of the algorithm, there's no direct way to check if N is prime.
To check if N is prime, first, you can use the easy divisors (2, 5, 7, etc), then you can generates all the Atkin primes under N, and then try to divide N by each Atkin prime. If it's divisible, then you return false. If not, then I'm afraid you will have to test all the numbers under N....
Maybe you can use some probabilistic approach, which can be far more efficient to check a single number. Try methods like Miller–Rabin or Solovay–Strassen primality test (used in RSA).
I think you will be happy : here's an implementation of Solovay, and here's an very interesting page about all the primality testing algorithms.
回答2:
There are several related problems that you should solve in different ways:
- Finding all prime factors of a given composite number: Depending on the size, you should use Pollard rho, the elliptic curve method, the quadratic sieve, or the number field sieve for this. Factoring numbers takes a long time in general.
- Testing whether a given number is prime: You should use Miller-Rabin for this. It is tremendously fast, and it circumvents the "factoring numbers is slow" problem by using a characterisation of the prime numbers other than "those that have no nontrivial factors."
- Finding all primes in a range: Use the sieve of Eratosthenes for ranges close to zero or the sieve of Atkin for ranges farther away from zero.
You are asking about applying the sieve of Atkin to either test primality or factor a number into primes. This is the wrong way to go about either problem.
来源:https://stackoverflow.com/questions/28520359/prime-numbers-using-sieve-of-atkin-with-biginteger