我尝试使用Sieve Eratosthenes方法列出最多20亿的素数。这是我用的!
我面临的问题是,我无法超越一千万个数字。当我尝试时,它说“分段错误”。我在互联网上搜索找到原因。有些网站说,这是编译器本身的内存分配限制。有人说,这是一个硬件限制。我使用的是安装了4GB RAM的64位处理器。请建议我列出它们的方法。
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000000
long int mark[MAX] = {0};
int isone(){
long int i;
long int cnt = 0;
for(i = 0; i < MAX ; i++){
if(mark[i] == 1)
cnt++;
}
if(cnt == MAX)
return 1;
else
return 0;
}
int main(int argc,char* argv[]){
long int list[MAX];
long int s = 2;
long int i;
for(i = 0 ; i < MAX ; i++){
list[i] = s;
s++;
}
s = 2;
printf("\n");
while(isone() == 0){
for(i = 0 ; i < MAX ; i++){
if((list[i] % s) == 0)
mark[i] = 1;
}
printf(" %lu ",s);
while(mark[++s - 2] != 0);
}
return 1;
}
答案 0 :(得分:6)
long int mark[1000000]
执行堆栈分配,这不是您想要的内存量。尝试long int *mark = malloc(sizeof(long int) * 1000000)
来分配堆内存。这将使你超过〜1万个数组元素。
记住free
内存,如果你不再使用它。如果你不知道malloc或free,请阅读这些函数的联机帮助页(手册),可以在任何linux终端上通过man 3 malloc
和man 3 free
获得。 (或者您可以只是谷歌man malloc
)
编辑:使calloc(1000000, sizeof(long int))
具有0初始化数组,这可能更好。
此外,您可以将数组的每个元素用作位掩码,以便每位存储一个标记,而不是每个sizeof(long int)字节。我建议对数组元素使用固定宽度整数类型,如uint32_t
,然后将数组的(n % 32)
'元素中的(n / 32)
'位设置为1将第n个元素设置为1。
您可以使用:
设置整数i
的第n位
uint32_t i = 0;
i |= ((uint32_t) 1) << n
假设您从0开始计数。
使你在uint32_t位掩码数组上的set操作得到一个数字n:
mask[n / 32] |= ((uint32_t)1) << (n % 32)
为32位类型节省了大约99%的内存。玩得开心:D
这里使用的另一种更先进的方法是素轮分解,这基本上意味着您事先将2,3和5(甚至可能更多)声明为素数,并且仅使用不能被其中一个整除的数字。你的面具阵列。但这是一个非常先进的概念。
然而,我已经用约15行代码(也用于projecteuler)在C中写了2和3的质量分数因子分解,因此可以有效地实现这些东西;)
答案 1 :(得分:2)
最直接的改进是切换到代表奇数的位。因此,要覆盖M=
20亿个数字或10亿个赔率,您需要1000/8 = 1.25亿个字节= ~120 MB的内存(在堆上分配它们,仍然使用calloc
函数) 。
位置i
的位代表数字2*i+1
。因此,当标记素数p
的倍数时,即p^2, p^2+2p, ..., M
,我们p^2=(2i+1)^2=4i^2+4i+1
由位置j=(p^2-1)/2=2i(i+1)
处的一位代表,以及p
的下一个倍数位于p=2i+1
,
for( i=1; ; ++i )
if( bit_not_set(i) )
{
p=i+i+1;
k=(p-1)*(i+1);
if( k > 1000000000) break;
for( ; k<1000000000; k+=p)
set_bit(k); // mark as composite
}
// all bits i>0 where bit_not_set(i) holds,
// represent prime numbers 2i+1
下一步是切换到适合您的缓存大小的较小段。这应该加快速度。您只需要为20亿平方根的平均值保留存储区域,即44721.
首先,筛选这个较小的区域,找到那里的素数;然后将这些素数写入单独的int
数组;然后使用这个素数数组来筛选每个段,可能会将找到的素数打印到stdout
或其他任何部分。