c - 在 C 中使用 GMP 5.0.2 的斐波那契函数

标签 c fibonacci gmp

我使用 GMP 5.0.2 库中的类型和函数编写了斐波那契函数。但是我编译的时候一直报错。以下是错误和代码:

main.c:4:7: error: ‘fib’ declared as function returning an array
main.c: In function ‘main’:
main.c:21:10: error: incompatible types when assigning to type ‘mpz_t’ from type ‘int’
main.c: At top level:
main.c:32:7: error: ‘fib’ declared as function returning an array
main.c: In function ‘fib’:
main.c:33:28: warning: return makes integer from pointer without a cast [enabled by default]
main.c:44:3: warning: passing argument 2 of ‘__gmpz_set’ makes pointer from integer without a cast [enabled by default]
/usr/local/include/gmp.h:1074:21: note: expected ‘mpz_srcptr’ but argument is of type ‘int’
main.c:45:3: warning: passing argument 2 of ‘__gmpz_set’ makes pointer from integer without a cast [enabled by default]
/usr/local/include/gmp.h:1074:21: note: expected ‘mpz_srcptr’ but argument is of type ‘int’
main.c:47:3: error: too few arguments to function ‘__gmpz_add’
/usr/local/include/gmp.h:696:21: note: declared here

代码是

#include <stdio.h>
#include <gmp.h>

mpz_t fib (mpz_t, const mpz_t);

int main (void) {
    printf("Before anything\n"); // debugging

    mpz_t FOUR; mpz_init(FOUR); mpz_add_ui(FOUR, FOUR, 4);

    printf("Declare FOUR, initilize it, set it to 4\n"); // debugging

    mpz_t N; mpz_init(N); mpz_add_ui(N, N, 5);

    printf("Declare N, initilize it, set it to 5\n"); // debugging

    mpz_t fibFive; mpz_init(fibFive);

    printf("Declare fibFive, initilize it\n"); // debugging

    fibFive = fib(N, FOUR);

    printf("After calling the fib function on fibFive\n"); // debugging

    gmp_printf("5th fibonacci number is %Zd\n", fibFive);

    printf("the end\n"); // debugging

    return 0;
}

mpz_t fib (mpz_t n, const mpz_t baseCase) {
    if (mpz(n, baseCase) < 0) return n;
    else {
        mpz_t a, b;
        mpz_t t1, t2;

        mpz_init(a); mpz_init(b);
        mpz_init(t1); mpz_init(t2);

        mpz_sub_ui(t1, n, 2);
        mpz_sub_ui(t2, n, 1);

        mpz_set(a, fib(t1, baseCase));
        mpz_set(b, fib(t2, baseCase));

        return mpz_add(a, b);
    }
}

对于编译,我使用了 gcc main.c -lgmp

注意:我阅读了 GMP 手册并使用了整数函数手册中代码中的函数 GMP 5.0.2 Manual - Integer Functions

最佳答案

gmp.h的相关部分(我不知道我安装的次要版本,但在GMP 4中已经相同,我预计不会很快改变)是

typedef struct
{
  int _mp_alloc;            /* Number of *limbs* allocated and pointed
                               to by the _mp_d field.  */
  int _mp_size;             /* abs(_mp_size) is the number of limbs the
                               last field points to.  If _mp_size is
                               negative this is a negative number.  */
  mp_limb_t *_mp_d;         /* Pointer to the limbs.  */
} __mpz_struct;

#endif /* __GNU_MP__ */


typedef __mpz_struct MP_INT;    /* gmp 1 source compatibility */
typedef __mpz_struct mpz_t[1];

所以 mpz_t 是一个包含 __mpz_struct 的长度为 1 的数组。这就是原因

main.c:4:7: error: ‘fib’ declared as function returning an array

之类的。如果没有原型(prototype),编译器显然会假定隐式 int,因此

fibFive = fib(N, FOUR);

原因

main.c:21:10: error: incompatible types when assigning to type ‘mpz_t’ from type ‘int’

要修复它,您必须将 mpz_t 作为输出参数传递给您的函数,并进行最小的更改(不是您的索引已关闭,F(0) = 0 按照惯例):

#include <stdio.h>
#include <gmp.h>

void fib (mpz_t, mpz_t, const mpz_t);

int main (void) {
    printf("Before anything\n"); // debugging

    mpz_t FOUR; mpz_init(FOUR); mpz_add_ui(FOUR, FOUR, 4);

    printf("Declare FOUR, initilize it, set it to 4\n"); // debugging

    mpz_t N; mpz_init(N); mpz_add_ui(N, N, 5);

    printf("Declare N, initilize it, set it to 5\n"); // debugging

    mpz_t fibFive; mpz_init(fibFive);

    printf("Declare fibFive, initilize it\n"); // debugging

    fib(fibFive, N, FOUR);

    printf("After calling the fib function on fibFive\n"); // debugging

    gmp_printf("5th fibonacci number is %Zd\n", fibFive);

    printf("the end\n"); // debugging

    return 0;
}

void fib (mpz_t res, mpz_t n, const mpz_t baseCase) {
    if (mpz_cmp(n, baseCase) < 0){
        mpz_set(res,n);
    } else {
        mpz_t a, b;
        mpz_t t1, t2;

        mpz_init(a); mpz_init(b);
        mpz_init(t1); mpz_init(t2);

        mpz_sub_ui(t1, n, 2);
        mpz_sub_ui(t2, n, 1);

        fib(a, t1, baseCase);
        fib(b, t2, baseCase);

        mpz_add(res, a, b);
    }
}

关于c - 在 C 中使用 GMP 5.0.2 的斐波那契函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12730094/

相关文章:

c - 我是否必须考虑控制流图中的预处理器指令?

c++ - main() 中的 return 语句与 exit()

gcc - 如何在没有共享库的情况下使用 GMP、MPFR、MPC、ELF 逐个安装 GCC?

c - gmp库的mdi_init的C实现

c - C99 是否强制要求 `int64_t` 类型始终可用?

python - 写一个递归函数来解决斐波那契

java - 如何将 BigInteger 与数组一起使用?

recursion - Fortran 中的递归子例程如何工作?

c++ - QByteArray 转换为十六进制失败

c - 连接时出现 Strcat 问题