我想找到两个13位数字(1,000,000,000,000和1,000,000,100,000)之间的素数...我使用unsigned long long
或long long int
和scanf
之类的%llu
和%lld
但这不起作用。我怎样才能做到这一点?我使用这样的代码:
int main()
{
long long int n1, n2, i;
int flag, j;
printf("Enter two numbers (intervals): ");
scanf("%lld %lld", &n1, &n2);
printf("Prime numbers between %lld and %lld are: ", n1, n2);
for(i=n1+1; i<n2; ++i)
{
flag=0;
for(j=2; j<=i/2; ++j)
{
if(i%j==0)
{
flag=1;
break;
}
}
if(flag==0)
printf("%lld ",i);
}
return 0;
}
答案 0 :(得分:1)
j
是int
,可能是32位类型,而i
是long long int
,大概是64位类型。由于i
大于2³,因此值i/2
大于int
类型的最大值,即2³¹-1。因此,比较j<=i/2
始终为真,并且循环for(j=2; j<=i/2; ++j)
永远不会通过正文内的break
停止。但只有当break
是j
的除数时才会调用此i
,这在i
为素数时永远不会发生。
如果您将j
更改为long long int
,我认为您的程序有效,但需要很长时间才能完成内循环 - n1/2
次迭代。一个简单的改进是停在i
的平方根而不是i
的一半。仅这一点就可以使我的机器上的程序运行得很好。
您应该在每次fflush(stdout);
调用后添加printf
,否则输出将被缓冲,直到程序退出。或者,首先调用setbuf(stdout, NULL)
以结果输出缓冲。
这种天真的算法肯定可以改进:它重复了很多计算。您可以将信息存储在内存中,以避免反复进行相同的测试;这是时间/记忆权衡。 sieve of Eratosthenes是一个相当简单的算法,需要权衡到另一个极端:它维护一个sqrt(n2)位表,其中第k个条目表示k是否为素数。这在这里是可行的。您还可以查看开源BSD primes
utility,看看他们是如何做到的。