我在Eular问题页面上做了另一个问题。 低于10的素数之和为2 + 3 + 5 + 7 = 17。 找出200万以下所有素数的总和。
我已经成功编写了下面的代码,但我认为在某个地方(即当我们得到大素数时)代码会失去准确性。答案应该是142913828922,但我得到1179908154.
我不知道为什么我没有得到答案,因为下面的代码适用于10岁以下。
任何帮助都会很棒。我做这些问题的原因是为了在C中变得更好。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* Initialise */
void CalcNumber(unsigned long number);
int isPrime(unsigned long number);
/* Functions*/
void CalcNumber(unsigned long number)
{
unsigned long i = 1;
unsigned long prime = 0;
while(i != number)
{
i++;
if(isPrime(i))
{
printf("prime: %lu\n", i);
prime += i;
}
}
printf("The sum of primes under %lu: %lu\n",number, prime);
printf("count: %d\n", i);
}
int isPrime(unsigned long number)
{
int i, nb, count, test,limit;
test = count = 0;
nb = number;
limit = sqrt(nb) + 1;
if(nb == 2)
{
return 1;
}
if (nb % 2 == 0)
test = 1;
else{
for (i = 3 ; i < limit && ! test; i+=2, count++)
if (nb % i == 0)
test = 1;
}
if (!test)
return 1;
else
return 0;
}
int main(void)
{
unsigned long number;
printf("Enter a number: \n");
scanf("%ul", &number );
CalcNumber(number);
return EXIT_SUCCESS;
}
答案 0 :(得分:4)
考虑到数字的长度,您应该使用长度至少为64位的数据类型。较新的C99标准包括至少64位的long long
(和unsigned long long
)数据类型。如果您需要printf
,则必须使用"%lld"
和"%llu"
。
答案 1 :(得分:2)
void CalcNumber(unsigned long number)
{
unsigned long i = 1;
unsigned long prime = 0;
while(i != number)
{
i++;
if(isPrime(i))
{
printf("prime: %lu\n", i);
prime += i;
}
}
请注意,您需要检查的数字大约是您需要的数字的两倍。唯一的偶数素数是2
,因此除了3
之外的奇数以外的任何其他内容都没有检查 - 并添加1+2
&#34;手工&#34;。你也可以在这里使用i += 2;
。
您的isPrime()
方法会重新计算大量信息。
但是,如果您真的想继续使用当前的isPrime()
方法,我想提供一个非常强烈的提示,即您完全删除test
变量并{当您知道某个号码不是素数时,立即从 方法中{1}}。这将使代码更容易阅读和更容易调试。
考虑编写一些专门测试return
的测试用例。查看常见嫌疑人:1,2,3,4,5,7,8,9,15,16,17等。
答案 2 :(得分:2)
存储素数之和的变量是无符号长整数,无符号长整数是0到4294967295.它不能保存142913828922数。 142913828922 mod(4294967295 + 1)= 1179908154
更改您的数据类型