1
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.

Find the sum of all the primes below two million.

我的回答是:

bool IsRishoni;
int soap = 0;
for (int i = 3; i < 2000000; i++)
{
    IsRishoni = true;
    for (int a = 2; (a <= Math.Sqrt(i)) && (IsRishoni); a++)
    {
        if (i % a == 0)
            IsRishoni = false;
    }
    if (IsRishoni)
    {
        soap = i + soap;
    }
}
Console.WriteLine(soap + 2);
Console.ReadLine();

为什么这不起作用?我得到的答案是 1179908154 ...请帮助。

4

3 回答 3

6

代替

soap = i + soap;

soap = checked(i + soap);

..问题应该暴露出来。

这个问题有更多细节:No overflow exception for int in C#?

于 2012-04-28T08:11:02.483 回答
2

您的答案(存储在 中soap)是一个大于int.Maxvalue(2,147,483,647) 的值。

你的答案是 ~ 150,000,000,000

换句话说,您需要使用比这更大的数据类型。

long.MaxValue = 9,223,372,036,854,775,807
int.Maxvalue = 2,147,483,647
于 2012-04-28T08:05:09.027 回答
1

您所追求的结果可能太大而无法通过 32 位有符号整数 ( int) 来表示。

让我们首先通过假设所有数字都是素数来确定结果的上限。通过求和,我们知道直到N(包括)所有数字的总和是N * (N + 1) / 2;因此,直到 2,000,000 的所有素数之和的上限为 2,000,001,000,000。这大于int2,147,483,647 所允许的最大值,因此您可能会得到一个被默默忽略的数字溢出。

如果您想要更准确地估计您的答案,您可以使用素数定理,它指出 0 和N素数之间的随机整数的概率约为1 / ln(N)。结合我们之前的公式,所有素数的近似和NN * (N + 1) / (2 * ln(N))。对于 2,000,000,计算结果约为 138,000,000,000,仍大于 的最大值int

要解决您的问题,您只需将用于soap变量的整数数据类型切换为 64 位整数表示,例如long. 它的最大值是9,223,372,036,854,775,807,所以它肯定可以代表你的数字。

long soap = 0;

单独说明:由于您使用的是素数序列,因此如果您将实现更改为 Eratosthenes 筛,您可以获得巨大的性能提升(至少 100 倍)。

于 2012-04-28T08:29:53.703 回答