|
20鱼币
原题:题目2:在斐波那契数列中,找出4百万以下的项中值为偶数的项之和
描述:在使用通项公式计算斐波那契第n项值的过程中要用到double型,但是斐波那契数列在20项以后会变得很大很大,这使得用浮点计算后的误差也变得很大很大,得不到精确的整数值。
问题:对于浮点数转化为整型有没有更准确的解决办法?该题中有没有时间开销比较小的算法?
代码片段如下,万分感谢。
通项公式法求第n项
- //通项公式求数列第n项 a_n = (1/sqrt(5))*(pow((sqrt(5)+1)/2,n)+pow((sqrt(5)-1)/2,n))
- #define F2_FIBONACCI_SWITCH
- #ifdef F2_FIBONACCI_SWITCH
- #include "math.h"
- #define T_1 0.44721359549995f
- #define T_2 1.61803398874989f //浮点运算会带来误差
- #define T_3 0.61803398874989f
- unsigned long int Fibonacci(int n){
- double tmp = 0.0f;
- tmp = T_1*(pow(T_2,n)+pow(T_3,n));
- return (unsigned long int)(tmp); //在整型转换过程中,大数计算误差很大,得错误值
- }
- #endif
复制代码
递推法求第n项
- #define F1_FIBONACCI_SWITCH
- #ifdef F1_FIBONACCI_SWITCH
- unsigned long int Fibonacci(int n){
- unsigned long int f1=1,f2=1,temp;
- if (n<3) return 1;
- for (int i = 1; i < n; i++) {
- temp = f1;
- f1 = f2;
- f2 = temp +f1;
- }
- return f1;
- }
- #endif
复制代码
完整代码
- /*
- * 题目2:在斐波那契数列中,找出4百万以下的项中值为偶数的项之和
- */
- #include <stdio.h>
- unsigned long int Fibonacci(int n);
- int IsEven(unsigned long int n);
- int main(){
- unsigned long int sum = 0;
- int k = 1;
- for (unsigned long int i = 1; i < 4000000;) {
- i=Fibonacci(k++);
- printf("%ld ",i);
- IsEven(i) && (sum+=i);
- }
- printf("\n%ld\n",sum);
- return 0;
- }
- #define F1_FIBONACCI_SWITCH
- #ifdef F1_FIBONACCI_SWITCH
- unsigned long int Fibonacci(int n){
- unsigned long int f1=1,f2=1,temp;
- if (n<3) return 1;
- for (int i = 1; i < n; i++) {
- temp = f1;
- f1 = f2;
- f2 = temp +f1;
- }
- return f1;
- }
- #endif
- int IsEven(unsigned long int n){
- return n%2?0:1;
- }
- //通项公式求数列第n项 a_n = (1/sqrt(5))*(pow((sqrt(5)+1)/2,n)+pow((sqrt(5)-1)/2,n))
- //#define F2_FIBONACCI_SWITCH
- #ifdef F2_FIBONACCI_SWITCH
- #include "math.h"
- #define T_1 0.44721359549995f
- #define T_2 1.61803398874989f //浮点运算会带来误差
- #define T_3 0.61803398874989f
- unsigned long int Fibonacci(int n){
- double tmp = 0.0f;
- tmp = T_1*(pow(T_2,n)+pow(T_3,n));
- return (unsigned long int)(tmp); //在整型转换过程中,大数计算误差很大,得错误值
- }
- #endif
复制代码
本帖最后由 sunrise085 于 2021-2-2 13:53 编辑
浮点型转整型,有精度损失是必然的,这是他们的存储方式导致的,没有解决办法。
而且long本来就满足数据大小的要求了,何必非要去使用double来降低精度
斐波那契数列不要用通项公式求了。直接用基本方法累加就挺简单的啊
想找时间开销少的方法,直接写程序,不要花里胡哨的写好几个函数,能省去不少时间
- #include <stdio.h>
- int main(){
- unsigned long int sum = 0,i=1,temp1=1,temp2;
- int k = 1;
- for (; i < 4000000;) {
- if(i%2==0){
- printf("%d:%ld \n",k++,i);//若只是完成功能,则删掉这一行,printf特别消耗时间!!
- sum+=i;
- }
- temp2=i;
- i=temp1;
- temp1=i+temp2;
- }
- printf("\nsum=%ld\n",sum);
- return 0;
- }
复制代码
|
最佳答案
查看完整内容
浮点型转整型,有精度损失是必然的,这是他们的存储方式导致的,没有解决办法。
而且long本来就满足数据大小的要求了,何必非要去使用double来降低精度
斐波那契数列不要用通项公式求了。直接用基本方法累加就挺简单的啊
想找时间开销少的方法,直接写程序,不要花里胡哨的写好几个函数,能省去不少时间
|