输入太大时算法返回垃圾?

时间:2012-12-11 03:57:14

标签: c algorithm primes

我今天开始研究Project Euler问题,让自己忙于休息。其中一个问题是要求所有素数低于200万的总和,所以我把Eratosthenes的筛子拼凑起来找到所有这些数字。

unsigned long i, j, sum = 0, limit = 2000000;

// Allocate an array to store the state of numbers (1 is prime, 0 is not).
int* primes = malloc(limit * sizeof(int));

// Initialize every number as prime.
for (i = 0; i < limit; i++)
    primes[i] = 1;

// Use the sieve to check off values that are not prime.
for (i = 2; i*i < limit; i++)
    if (primes[i] != 0)
        for (j = 2; i*j < limit; j++)
            primes[i*j] = 0;

// Get the sum of all numbers still marked prime.
for (i = 2; i < limit; i++)
    if (primes[i] != 0)
        sum += i;

printf("%d", sum);

这完全适用于limit大约五十万。在此之后,它返回随机值(例如,1000000返回-1104303641)。我已经尝试将所有unsigned long变量声明为unsigned long long无效。错误似乎发生在最后4行,因为primes[]在此时只包含1和0。我认为这与正在使用的值的大小有关,任何人都可以提供任何指导吗?

2 个答案:

答案 0 :(得分:6)

Wolfram Alpha告诉我,小于500000的素数之和为9914236195

该数字不适合32位整数,因此在求和循环期间溢出int。您可以尝试使用uint64_t,但这个问题最终会以足够高的限制再次发生(尽管我怀疑限制为2000000)。

答案 1 :(得分:3)

将%d更改为%ld,您应该:

142913828922

这似乎应该是(接近或)正确答案。

..假设你的长期不是32位。

如果您使用的是32位平台,那么您将需要某种第三方大型int库。

BigInteger in C?

建议:http://gmplib.org/