C 如何改进寻找孪生素数

C 如何改进寻找孪生素数,c,primes,gmp,C,Primes,Gmp,所以我使用C语言上的GMP库来寻找高于某个值的双素数。虽然我相信我的策略会起作用,但问题在于它需要大量的时间(我知道你得到的值越高,寻找素数就越困难)。有没有办法优化搜索?下面是我的一段代码: mpz_ui_pow_ui(a, base, exponent); mpz_nextprime(b, a); // b is the next prime number after a. // c and d will be prime +

所以我使用C语言上的GMP库来寻找高于某个值的双素数。虽然我相信我的策略会起作用,但问题在于它需要大量的时间(我知道你得到的值越高,寻找素数就越困难)。有没有办法优化搜索?下面是我的一段代码:

    mpz_ui_pow_ui(a, base, exponent);
    mpz_nextprime(b, a); // b is the next prime number after a.
                         // c and d will be prime + 2 and
                         // prime - 2.

    /* Fortunate of fortunalities, mpz_nextprime gives the next
       prime greater than what one adds in! */
    /* We need to test if numbers are prime too. */
    while (al == false) {
        mpz_add_ui (c, b, 2);
        mpz_add_ui (d, b, -2);
        if ((mpz_probab_prime_p(c, 15) == 2) ||
            (mpz_probab_prime_p(d, 15) == 2)) { // Returns 2
                                                // if c/d are
                                                // definitely
                                                // prime.
            mpz_set(firstprime,b); 
            al == true;
            break;
        }
        {
            mpz_nextprime(b, b); // b is the next prime number
                                 // after a. c and d will be
                                 // prime + 2 and prime - 2.
        }
    }
    printf("first twin is: ");
    mpz_out_str(stdout, 10, firstprime);
    printf("\n");
    printf("second twin is: ");
    if (mpz_probab_prime_p(c, 15) == 2) {
        mpz_out_str(stdout, 10, c);
    } else {
        mpz_out_str(stdout, 10, d);
    }
    printf ("\n");

没有必要测试b-2是否可以素数,因为b是下一个大于a的素数。这将使您的搜索时间减少一半。对于非常大的数字来说,可能仍然太长。

您的算法有点奇怪。您不会测试
b
本身是否是素数,而是测试
b-2
b+2
中的一个或两个。然后,如果其中任何一个肯定是素数,则声明
b
是孪生素数之一

mpz_nextprime
可能返回非素数,因为它使用的是概率算法

@chqrlie指出
b-2
已经被
mpz_nextprime
处理过,这是正确的。唯一的边缘情况是,如果对
mpz\u nexttime
的第一次调用导致距离
a
只有一两个数字

既然你愿意接受
b
只是一个素数,那么如果两者都是素数,你应该感到高兴。因此:

/* a won't be prime */
mpz_ui_pow_ui(a, base, exponent);

if (exponent == 0) {
    mpz_nextprime(firstprime, a);
} else {
    /* Handle the edge case of a - 1 and a + 1 being twins */
    mpz_sub_ui(b, a, 2);
    mpz_nextprime(firstprime, b);
}

for (;;) {
    mpz_add_ui(c, firstprime, 2);
    if (mpz_probab_prime_p(c, 15) > 0) {
        break;
    }
    /* Optimize out an mpz_set call, thanks @chqrlie */
    mpz_nextprime(firstprime, c);
}

可能会找到孪生素数。如果您希望至少有一个是绝对素数,您可以实现自己的素数测试,或者为
firstprime
添加
mpz\u probab\u prime\p
调用
firstprime

还有其他检查大素数的方法,例如Miller-Rabin素数测试,没有穷尽地找到所有的低素数。您忽略了当
mpz\u probab\u prime\u p
c
d
返回1时的情况。mpz probab不使用Miller-Rabin。我不确定在
mpz\u nextprime
的两个参数中传递
b
是否安全。基数为2。指数是64。下一个素数在2^64之后找到素数。为什么(;;)的for循环是?我得到了中断,我的意思是for循环的条件不需要任何条件检查,因为我们只对
中断
感兴趣<(;;)
的code>与
的while(1)
相同。感谢您的帮助,我一直想知道如何更好地优化搜索,所以这是一个很好的研究方法。我完全忽略了下一个素数将使-1无效的事实@BrettHale:现在还不清楚
mpz\u probab\u prime\p
是否会以更高的迭代次数返回0或2。文档只是说更高的迭代次数只会增加返回值1实际上是2的概率。因此,唯一确定的方法是实现您自己的基本测试。