带有 GMP 库的斐波那契数
编辑:解决了。 ans var 需要在每次迭代中设置为 0。这是我忽略的一个错误。A mpz_set_ui(ans,0);在每个循环开始时解决问题。感谢 Oli Charlesworth 的努力!
我正在使用 GMP 库用 C 语言编写斐波那契函数,我使用矩阵乘法算法,但由于某些意外原因,我得到了错误的结果(我坚信该算法是正确的)。它一定与 GMP 有关结构和初始化。有什么想法吗?
/*********************************************************
Find n th Fibonacci number.Matrix algorithm.
+-- --+ +-- --+
|f(n+1) f(n) | | 1 1 | ^n
| | == | |
|f(n) f(n-1) | | 1 0 |
+-- --+ +-- --+
*********************************************************/
int
fastfib(mpz_t result,int n)
{
int cons[2][2]={{1,1},{1,0}}; //"constant" matrix
mpz_t mat[2][2]; //actual matrix holding fibonacci numbers
mpz_t ans; //holds f(n+1)
mpz_t return_val; //used for calculations
mpz_t temp; //used for calculations as well
//initialize (automatically set to zero)
mpz_init(ans);
mpz_init(return_val);
mpz_init(temp);
mpz_init(mat[0][0]);
mpz_init(mat[0][1]);
mpz_init(mat[1][0]);
mpz_init(mat[1][1]);
//start with n=1
mpz_set_ui(mat[0][0],1);
mpz_set_ui(mat[1][0],1);
mpz_set_ui(mat[0][1],1);
mpz_set_ui(mat[1][1],0);
//some trivial cases
if(n==0){
mpz_set_ui(result,0);
return 0;
}
if(n==1){
mpz_set_ui(result,1);
return 0;
}
if(n==2){
mpz_set_ui(result,1);
return 0;
}
n--;
while(n>1){
//fib[n+1]
//ans=mat[0][0]*cons[0][0]+mat[0][1]*cons[1][0];
mpz_set_ui(ans,0);
mpz_mul_ui(temp,mat[0][0],cons[0][0]);
mpz_add(ans,ans,temp);
mpz_mul_ui(temp,mat[0][1],cons[1][0]);
mpz_add(ans,ans,temp);
//update matrix
mpz_set(mat[1][1],mat[1][0]); //mat[1][1]=mat[1][0];
mpz_set(mat[1][0],mat[0][0]); //mat[0][1]=mat[1][0]=mat[0][0];
mpz_set(mat[0][1],mat[0][0]);
mpz_set(mat[0][0],ans); //mat[0][0]=ans;
n--;
}
//clear vars
mpz_clear(ans);
mpz_clear(return_val);
mpz_clear(temp);
mpz_set(result,mat[0][0]);
return 0;
}
一些调试信息
results for n=2 // expected
2 1 // 2 1
1 1 // 1 1
results for n=3
5 2 // 3 2
2 1 // 2 1
results for n=4
12 5 // 5 3
5 2 // 3 2
results for n=5
29 12 // 8 5
12 5 // 5 3
results for n=6
70 29 // 13 8
29 12 // 8 5
70
EDIT: solved. ans var needed to be set to 0 in every iteration.That was a mistake I overlooked.A mpz_set_ui(ans,0); at the beginning of each loop solves the problem.Thanks to Oli Charlesworth for his effort!
I'm coding a fibonacci function in C using the GMP library,I use the matrix multiplication algorithm,but for some unexpected reason,I get wrong results(I strongly believe that the algorithm is right).It must have something to do with Gmp structs and inits.Any ideas?
/*********************************************************
Find n th Fibonacci number.Matrix algorithm.
+-- --+ +-- --+
|f(n+1) f(n) | | 1 1 | ^n
| | == | |
|f(n) f(n-1) | | 1 0 |
+-- --+ +-- --+
*********************************************************/
int
fastfib(mpz_t result,int n)
{
int cons[2][2]={{1,1},{1,0}}; //"constant" matrix
mpz_t mat[2][2]; //actual matrix holding fibonacci numbers
mpz_t ans; //holds f(n+1)
mpz_t return_val; //used for calculations
mpz_t temp; //used for calculations as well
//initialize (automatically set to zero)
mpz_init(ans);
mpz_init(return_val);
mpz_init(temp);
mpz_init(mat[0][0]);
mpz_init(mat[0][1]);
mpz_init(mat[1][0]);
mpz_init(mat[1][1]);
//start with n=1
mpz_set_ui(mat[0][0],1);
mpz_set_ui(mat[1][0],1);
mpz_set_ui(mat[0][1],1);
mpz_set_ui(mat[1][1],0);
//some trivial cases
if(n==0){
mpz_set_ui(result,0);
return 0;
}
if(n==1){
mpz_set_ui(result,1);
return 0;
}
if(n==2){
mpz_set_ui(result,1);
return 0;
}
n--;
while(n>1){
//fib[n+1]
//ans=mat[0][0]*cons[0][0]+mat[0][1]*cons[1][0];
mpz_set_ui(ans,0);
mpz_mul_ui(temp,mat[0][0],cons[0][0]);
mpz_add(ans,ans,temp);
mpz_mul_ui(temp,mat[0][1],cons[1][0]);
mpz_add(ans,ans,temp);
//update matrix
mpz_set(mat[1][1],mat[1][0]); //mat[1][1]=mat[1][0];
mpz_set(mat[1][0],mat[0][0]); //mat[0][1]=mat[1][0]=mat[0][0];
mpz_set(mat[0][1],mat[0][0]);
mpz_set(mat[0][0],ans); //mat[0][0]=ans;
n--;
}
//clear vars
mpz_clear(ans);
mpz_clear(return_val);
mpz_clear(temp);
mpz_set(result,mat[0][0]);
return 0;
}
Some debug info
results for n=2 // expected
2 1 // 2 1
1 1 // 1 1
results for n=3
5 2 // 3 2
2 1 // 2 1
results for n=4
12 5 // 5 3
5 2 // 3 2
results for n=5
29 12 // 8 5
12 5 // 5 3
results for n=6
70 29 // 13 8
29 12 // 8 5
70
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决了。 ans var 需要在每次迭代中设置为 0。这是我忽略的一个错误。A mpz_set_ui(ans,0);在每个循环开始时解决问题。感谢 Oli Charlesworth 的努力!
solved. ans var needed to be set to 0 in every iteration.That was a mistake I overlooked.A mpz_set_ui(ans,0); at the beginning of each loop solves the problem.Thanks to Oli Charlesworth for his effort!