使用Atve筛选和BigInteger的素数

时间:2015-02-14 21:10:04

标签: c# math primes prime-factoring

有没有人碰巧知道使用BigInteger的C#Sieve of Atkin算法?根据我的理解,这是目前最着名的素数因子分解算法。

我目前有这个功能:

/// <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;

        }

但我希望有一个看起来更像下面的函数签名,所以如果数字为素数,它可以输入一个数字来测试并输出true。

public bool IsPrime(BigInteger number) { ... }

2 个答案:

答案 0 :(得分:3)

您应该以不同的方式解决几个相关的问题:

  • 查找给定复合数的所有素因子:根据大小,您应该使用Pollard rho,椭圆曲线法,二次筛或数字场筛。保理数字通常需要很长时间。
  • 测试给定数字是否为素数:您应该使用Miller-Rabin。这是非常快的,并且它绕过了因子数字很慢&#34;通过使用除了&#34之外的素数的特征来表示问题;那些没有非平凡因素的素数。&#34;
  • 查找范围内的所有质数:使用Eratosthenes的筛子接近零的范围或Atkin筛子的范围远离零。

你问的是将阿特金的筛子应用于测试素数或将数字作为素数。这是解决这两个问题的错误方法。

答案 1 :(得分:2)

我认为,根据算法的性质,没有直接的方法来检查N是否为素数。

要检查N是否为素数,首先,您可以使用简单除数(2,5,7等),然后您可以在N下生成所有Atkin素数,然后尝试将N除以每个Atkin素数。如果它可以被整除,那么你就会返回false。如果没有,那么我担心你必须测试N下的所有数字....

也许您可以使用一些概率方法,这可以更有效地检查单个数字。尝试使用Miller–RabinSolovay–Strassen素性测试(在RSA中使用)等方法。

我想你会很高兴:here's是Solovay的一个实现,here's是一个关于所有素性测试算法的非常有趣的页面。