查找质数。 6k + 1 6k-1

时间:2019-02-11 18:07:03

标签: c math primes

我正在尝试优化素数搜索算法。

我有一个程序可以找到(实际计数)低于某个限制的素数。我知道素数可以6k+1的形式6k-1k > 0表示。

对于目前的时间,我使用筛分算法将非素数分类。一些伪代码:

int P[100] = {1};
int m = 100;
int n = 2, k, i, j, sqrtm = (int)sqrt(m);
for(k = 2, i = 5; i < sqrtm + 1; i += k, k ^= 6)
 if(P[i])
  P[i] = 0;
  n = n + 1;
  for(j = i * i; j < m; j += 2 * i)
   P[j] = 0;

for(k = 2, i = 5; i < m + 1; i += k, k ^= 6)
 if(P[i])n = n + 1;

print n;

以上代码有望打印出小于m的质数。 我在这里和那里使用一些技巧来加快速度。例如,从'5'开始筛选非质数,使用这样的事实,即上述形式的质数不能为'2'和'3'的倍数。 6k + 2是偶数。 6k + 3是'3'的倍数,令x = 2k,6k + 3 => 3x + 3 => 3(x + 1)mod 3 == 0或3(2k + 1)mod 3 == 0。

在这里,我的问题出现了。如果我用一些质数进行预筛分,是否可以采用其他形式的质数来加快筛分循环? 例如,预先筛分2,3,5,7,11,13,17,19,23,29。因此,现在P数组没有以上的倍数。也许有人可以建议我某种形式的质数形式,例如,通过预筛分,可以完成更大的循环。

我已经做了一些与素数形式无关的优化。就像大块筛分并使用位集存储筛分一样。所有这些使我的程序运行起来非常快。

time ./np 1000000000
allocated 119Mb
primes from 2 <= 1000000000 : 50847534

real    0m2.386s
user    0m2.354s
sys 0m0.032s

我知道我可以从互联网上获得更好的素数计数器程序。而且它将运行得更快。但是我只想知道我自己可以走多远。和社区帮助;)

总结一下。我想使用预筛分。我认为它使我的比较更少,总的内部循环也更少。我问你,在知道筛分前的事实的情况下,如何用其他形式写素数?

1 个答案:

答案 0 :(得分:3)

您说,除了23以外,所有质数均采用2*3*k±1的形式(对于某些整数k> = 1)

您可以将其扩展到

2 * 3 * 5 * k±{1、7、11、13}(和2、3、5、7、11、13)

2 * 3 * 5 * 7 * k±{1、11、13、17、19、23、29、31、37、41、43、47、53、59、61、67、71、73, 79、83、89、97、101、103、107、109}(以及2、3、5、7、11、13、17、19、23、29、31、37、41、43、47、53 59,61,67,71,73,79,83,89,97)

实施此表格可能不会使您的程序更高效(但是您定义的效率更高)。您需要测量。

上面的值是直接通过移动电话输入的,而无需验证。使用后果自负。