项目欧拉10号#

时间:2012-04-28 07:58:41

标签: c#

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 ...请帮忙。

3 个答案:

答案 0 :(得分:6)

替换

soap = i + soap;

soap = checked(i + soap);

..问题应该暴露出来。

此问题有更多详情:No overflow exception for int in C#?

答案 1 :(得分: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

答案 2 :(得分:1)

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

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

如果您想要更准确地估算答案,可以使用prime number theorem,其中指出0和N之间的随机整数为素数的概率约为1 / ln(N) 。将此与我们之前的公式相结合,所有素数最多为N的总和为N * (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;

另请注意:由于您正在使用素数的序列,如果将实施更改为Sieve of Eratosthenes,则可以获得巨大的性能提升(至少100倍)