【问题标题】:Fibonacci numbers with GMP lib带有 GMP 库的斐波那契数
【发布时间】:2011-09-05 10:19:57
【问题描述】:

编辑:已解决。 ans var 需要在每次迭代中设置为 0。这是我忽略的一个错误。A mpz_set_ui(ans,0);在每个循环的开头解决问题。感谢 Oli Charlesworth 的努力!

我正在使用 GMP 库在 C 中编写一个斐波那契函数,我使用矩阵乘法算法,但由于一些意想不到的原因,我得到了错误的结果(我坚信该算法是正确的)。它必须有一些东西用 Gmp 结构和 inits 做。有什么想法吗?

/*********************************************************
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

【问题讨论】:

  • 嗯,什么时候出错了?第一次迭代后?你得到了什么结果?
  • 我无法使用 gmp 结构进行中断和调试...我不知道如何获取它们的值。我只能使用 gmp_print 获得最终结果。例如 fib 30 给出 44560482149当然不是这样。
  • 为什么不能在 while 循环的每次迭代中打印出矩阵?
  • n=2 的结果 2 1 1 1 个结果 n=3 5 2 2 1 个结果 n=4 12 5 5 2 个结果 n=5 29 12 12 5 个结果 n=6 70 29 29 12 我打印第一行,然后是第二行
  • 这有点难读。您能否更新您的答案以包含此信息,以便对其进行格式化。此外,您应该与 预期 输出进行比较,这样人们就不必自己弄清楚了。

标签: c gmp


【解决方案1】:

解决了。 ans var 需要在每次迭代中设置为 0。这是我忽略的一个错误。A mpz_set_ui(ans,0);在每个循环的开头解决问题。感谢 Oli Charlesworth 的努力!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 2015-06-05
    • 2014-05-23
    • 2014-05-03
    • 1970-01-01
    相关资源
    最近更新 更多