C 这个算法有什么问题?

C 这个算法有什么问题?,c,algorithm,C,Algorithm,我试图解决欧拉投影问题#2:找到高达4000000的fibonaci系列偶数项之和。例:最多1000,总和为2+8+34+144+610=798 现在,我的算法是从2开始每三个fibonaci数相加-因为每三个fibonaci数必然是偶数,遵循逻辑: 偶数:E,奇数:O O+E=O E+O=O O+O=E 1+2=3 2+3=5 5+3=8 (example) 因此,我编写了以下代码来找出答案 #include<stdio.h> #define LT

我试图解决欧拉投影问题#2:找到高达4000000的fibonaci系列偶数项之和。例:最多1000,总和为2+8+34+144+610=798

现在,我的算法是从2开始每三个fibonaci数相加-因为每三个fibonaci数必然是偶数,遵循逻辑:

偶数:E,奇数:O

O+E=O    E+O=O    O+O=E
1+2=3    2+3=5    5+3=8    (example)
因此,我编写了以下代码来找出答案

#include<stdio.h>
#define LT 4000000
int main()
{
    double i0,i1,sum=0,cycle,eSum=2,status=1;
    i0 = 1;
    i1 = 2;

    while(i1<LT && status == 1)
    {
        for(cycle=3;cycle>0;cycle--)
        {
            sum=i0+i1;
            i0=i1;
            i1=sum;

            if((i1+i0)>LT)
            {
                status = 0;
                break;
            }
        }
        eSum+=(status == 1)?sum:0;
    }
    printf("\nThe required Answer: %8.0f\n",eSum);
    return 0;
}
#包括
#定义LT 4000000
int main()
{
双i0,i1,和=0,循环,eSum=2,状态=1;
i0=1;
i1=2;
而(i10;循环--)
{
总和=i0+i1;
i0=i1;
i1=总和;
如果((i1+i0)>LT)
{
状态=0;
打破
}
}
eSum+=(状态==1)?总和:0;
}
printf(“\n所需答案:%8.0f\n”,eSum);
返回0;
}
现在,对于LT=1000,它可以正常工作,但是对于需要LT=4000000的问题,程序显示了错误的值1089154,而不是正确的值4613732


我想不出这个代码有什么问题。此外,我不明白它如何在LT=1000的情况下正常工作,但在更大的数字下却不能正常工作。。我是不是错过了一些让人难堪的显而易见的东西?请帮助。

内部看起来像是一种结构,自然数不应该使用double。 试着这样做:

#include<stdio.h>
#define LT 4000000
int main()
{
  long i0,i1,sum=0,eSum=2;
  int counter = 0;
  i0 = 1;
  i1 = 1;

  while(sum<LT)
  {
    sum=i0+i1;
    i0=i1;
    i1=sum;

    eSum+=((counter++ % 3 == 0) && ( sum <= LT))?sum:0;
  }
  printf("\nThe required Answer: %8.0f\n",eSum);
  return 0;
}
#包括
#定义LT 4000000
int main()
{
长i0,i1,和=0,eSum=2;
int计数器=0;
i0=1;
i1=1;

而(sumOP过早退出循环。将测试更改为
sum
,而不是
i1+i0
,后者是下一个
sum

    for(cycle=3;cycle>0;cycle--) {
        sum=i0+i1;
        i0=i1;
        i1=sum;
        // if((i1+i0)>LT)
        if(sum>LT)
        {
            status = 0;
            break;
        }
    }
由于您的数字在[1…2*4000000]范围内,因此使用
long
unsigned long
float
double
,您将获得可接受的结果。由于这是一个整数问题,建议使用整数。

为什么不简单地这样做

#include <stdio.h>
#include <inttypes.h>
#define LT 4000000
typedef uint64_t Numtype;
int main( void )
{
    Numtype n0 = 1;
    Numtype n1 = 1;
    Numtype n2 = 0;
    Numtype sum = 0;
    for(;;)
    {
        n2 = n0 + n1;
        if ( n2 > LT ) break;
        if ( n2 % 2 == 0 ) sum += n2;
        n0 = n1;
        n1 = n2;
    }

    printf("\nThe required Answer: %ld\n", sum);
    return 0;
}
#包括
#包括
#定义LT 4000000
typedef uint64_t Numtype;
内部主(空)
{
Numtype n0=1;
Numtype n1=1;
Numtype n2=0;
Numtype sum=0;
对于(;;)
{
n2=n0+n1;
如果(n2>LT)破裂;
如果(n2%2==0)和+=n2;
n0=n1;
n1=n2;
}
printf(“\n所需答案:%ld\n”,总和);
返回0;
}

对于初学者,请使用long not double重新编码所有内容。提示:当您的数值算法适用于小数字,但对大数字无效时,请查找溢出。我认为PE#2的重点正是教您这一点。如果您需要64位整数,请在此给出大提示:在posix上,使用
\include
和uint64\t。对于Windows,请使用us我真的不认为原因是溢出,因为程序在打印大于4000000的双精度值时没有问题-甚至是双精度值的两倍..另外,根据dasblinkenlight的建议,我尝试将双精度值更改为long..仍然得到了错误的答案..这看起来很奇怪..@Somu
long
可能短至32位而
double
几乎总是可以表示高达2到51次方的整数。我试图避免除法和/或模运算,以将处理器开销保持在最低限度。@Somu在400万个数字上运行并不是真正的CPU使用率。只是不必担心效率。@H2CO3我知道,我只是想不使用divi这是一个额外的挑战。我已经这样做了(这就是我知道答案的原因),这对我来说只是一个练习。。