鱼C论坛

 找回密码
 立即注册
查看: 1763|回复: 1

[已解决]关于C语言计算斐波那契数列

[复制链接]
发表于 2021-2-2 11:51:58 | 显示全部楼层 |阅读模式
20鱼币
原题:题目2:在斐波那契数列中,找出4百万以下的项中值为偶数的项之和

描述:在使用通项公式计算斐波那契第n项值的过程中要用到double型,但是斐波那契数列在20项以后会变得很大很大,这使得用浮点计算后的误差也变得很大很大,得不到精确的整数值。

问题:对于浮点数转化为整型有没有更准确的解决办法?该题中有没有时间开销比较小的算法?

代码片段如下,万分感谢。

通项公式法求第n项
  1. //通项公式求数列第n项  a_n = (1/sqrt(5))*(pow((sqrt(5)+1)/2,n)+pow((sqrt(5)-1)/2,n))
  2. #define F2_FIBONACCI_SWITCH
  3. #ifdef F2_FIBONACCI_SWITCH

  4. #include "math.h"

  5. #define T_1 0.44721359549995f
  6. #define T_2 1.61803398874989f   //浮点运算会带来误差
  7. #define T_3 0.61803398874989f

  8. unsigned long int Fibonacci(int n){
  9.   double tmp = 0.0f;
  10.   tmp = T_1*(pow(T_2,n)+pow(T_3,n));
  11.   return (unsigned long int)(tmp);  //在整型转换过程中,大数计算误差很大,得错误值
  12. }

  13. #endif
复制代码


递推法求第n项
  1. #define F1_FIBONACCI_SWITCH
  2. #ifdef F1_FIBONACCI_SWITCH
  3. unsigned long int Fibonacci(int n){
  4.   unsigned long int f1=1,f2=1,temp;
  5.   if (n<3) return 1;
  6.   for (int i = 1; i < n; i++) {
  7.     temp = f1;
  8.     f1 = f2;
  9.     f2 = temp +f1;
  10.   }
  11.   return f1;
  12. }
  13. #endif
复制代码


完整代码
  1. /*
  2. * 题目2:在斐波那契数列中,找出4百万以下的项中值为偶数的项之和
  3. */

  4. #include <stdio.h>

  5. unsigned long int Fibonacci(int n);
  6. int IsEven(unsigned long int n);

  7. int main(){
  8.     unsigned long int sum = 0;
  9.     int k = 1;
  10.   for (unsigned long int i = 1; i < 4000000;) {
  11.     i=Fibonacci(k++);
  12.     printf("%ld ",i);
  13.     IsEven(i) && (sum+=i);
  14.   }
  15.   printf("\n%ld\n",sum);
  16.   return 0;
  17. }

  18. #define F1_FIBONACCI_SWITCH
  19. #ifdef F1_FIBONACCI_SWITCH
  20. unsigned long int Fibonacci(int n){
  21.   unsigned long int f1=1,f2=1,temp;
  22.   if (n<3) return 1;
  23.   for (int i = 1; i < n; i++) {
  24.     temp = f1;
  25.     f1 = f2;
  26.     f2 = temp +f1;
  27.   }
  28.   return f1;
  29. }
  30. #endif

  31. int IsEven(unsigned long int n){
  32.   return n%2?0:1;
  33. }

  34. //通项公式求数列第n项  a_n = (1/sqrt(5))*(pow((sqrt(5)+1)/2,n)+pow((sqrt(5)-1)/2,n))
  35. //#define F2_FIBONACCI_SWITCH
  36. #ifdef F2_FIBONACCI_SWITCH

  37. #include "math.h"

  38. #define T_1 0.44721359549995f
  39. #define T_2 1.61803398874989f   //浮点运算会带来误差
  40. #define T_3 0.61803398874989f

  41. unsigned long int Fibonacci(int n){
  42.   double tmp = 0.0f;
  43.   tmp = T_1*(pow(T_2,n)+pow(T_3,n));
  44.   return (unsigned long int)(tmp);  //在整型转换过程中,大数计算误差很大,得错误值
  45. }

  46. #endif
复制代码
最佳答案
2021-2-2 11:51:59
本帖最后由 sunrise085 于 2021-2-2 13:53 编辑

浮点型转整型,有精度损失是必然的,这是他们的存储方式导致的,没有解决办法。
而且long本来就满足数据大小的要求了,何必非要去使用double来降低精度
斐波那契数列不要用通项公式求了。直接用基本方法累加就挺简单的啊

想找时间开销少的方法,直接写程序,不要花里胡哨的写好几个函数,能省去不少时间
  1. #include <stdio.h>
  2. int main(){
  3.     unsigned long int sum = 0,i=1,temp1=1,temp2;
  4.     int k = 1;
  5.     for (; i < 4000000;) {
  6.         if(i%2==0){
  7.             printf("%d:%ld \n",k++,i);//若只是完成功能,则删掉这一行,printf特别消耗时间!!
  8.             sum+=i;
  9.         }
  10.         temp2=i;
  11.         i=temp1;
  12.         temp1=i+temp2;
  13.     }
  14.     printf("\nsum=%ld\n",sum);
  15.     return 0;
  16. }
复制代码

最佳答案

查看完整内容

浮点型转整型,有精度损失是必然的,这是他们的存储方式导致的,没有解决办法。 而且long本来就满足数据大小的要求了,何必非要去使用double来降低精度 斐波那契数列不要用通项公式求了。直接用基本方法累加就挺简单的啊 想找时间开销少的方法,直接写程序,不要花里胡哨的写好几个函数,能省去不少时间
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-2-2 11:51:59 | 显示全部楼层    本楼为最佳答案   
本帖最后由 sunrise085 于 2021-2-2 13:53 编辑

浮点型转整型,有精度损失是必然的,这是他们的存储方式导致的,没有解决办法。
而且long本来就满足数据大小的要求了,何必非要去使用double来降低精度
斐波那契数列不要用通项公式求了。直接用基本方法累加就挺简单的啊

想找时间开销少的方法,直接写程序,不要花里胡哨的写好几个函数,能省去不少时间
  1. #include <stdio.h>
  2. int main(){
  3.     unsigned long int sum = 0,i=1,temp1=1,temp2;
  4.     int k = 1;
  5.     for (; i < 4000000;) {
  6.         if(i%2==0){
  7.             printf("%d:%ld \n",k++,i);//若只是完成功能,则删掉这一行,printf特别消耗时间!!
  8.             sum+=i;
  9.         }
  10.         temp2=i;
  11.         i=temp1;
  12.         temp1=i+temp2;
  13.     }
  14.     printf("\nsum=%ld\n",sum);
  15.     return 0;
  16. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-2 04:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表