首页 文章

使用Malloc通过GMP处理大量数字

提问于
浏览
-1

已解决:

我觉得很蠢 . GMP很好,这是我的疏忽 . 使用 size_t mpz_sizeinbase (const mpz_t op, int base) 后,我意识到我用来复制结果的char数组太小了 . 增加它的大小解决了它 . 谢谢您的帮助!


我的任务是编写一个C程序,它计算从第1024个元素到第1048576个元素的斐波纳契数列的元素(从2的10次幂到2的20次幂,增加2的幂) . 为此,我'm using GMP library to handle the numbers. The problem is, that around the 17th power of 2, the number is so big, that even GMP can't处理它,这意味着我应该使用 malloc() .

这是我的 main() (我修改了粘贴的代码,取出了不必要的部分,如写入文件和时间测量,将用于程序的另一部分):

int main(){
    int powersOfTwo[11];
    char res[10000];
    char *c;
    c = res;

    for(int i = 0; i < 11; i++){
        powersOfTwo[i] = normalPower(2,i+10);
    }
    for(int i = 0; i < 11; i++){
        fibo(c, powersOfTwo[i]);
        printf("The %d th element of Fibonacci is %s\n",powersOfTwo[i],res);
        memset(res, 0, sizeof res);
    }

    return 0;
}

现在这里是简单的 normalPower 函数(为了清楚起见,与问题没有任何关系):

int normalPower(int n1, int n2){
    if(n2 == 0){
        return 1;
    }else{
        int temp = n1;
        for(int i = 1; i < n2; i++){
            temp *= n1;
        }
        return temp;
    }
}

现在问题, fibo 功能:

void fibo(char *c, int n){
    mpz_t *fib1;
    mpz_t *fib2;
    mpz_t *temp;

    fib1 = (mpz_t *) malloc(101000000 * sizeof(mpz_t));
    fib2 = (mpz_t *) malloc(101000000 * sizeof(mpz_t));
    temp = (mpz_t *) malloc(101000000 * sizeof(mpz_t));

    if (NULL == fib1 || NULL == fib2 || NULL == temp){
      printf("ERROR: Out of memory\n");
    }
    mpz_init(*fib1);
    mpz_init(*fib2);
    mpz_init(*temp);

    mpz_set_str(*fib1,"0",10);
    mpz_set_str(*fib2,"1",10);

    int i;
    if(n == 0){
      char *d = mpz_get_str(NULL,10,*fib1);
      strcpy(c,d);
    }

    if(n == 1){
      char *d = mpz_get_str(NULL,10,*fib2);
      strcpy(c,d);
    }

    if(n > 1){
      for(i = 1; i < n; i++){
          mpz_set(*temp, *fib2);
          mpz_add(*fib2, *fib1, *fib2);
          mpz_set(*fib1,*temp);

      }
      char *d = mpz_get_str(NULL,10,*fib2);
      strcpy(c,d);
    }

    free(fib1);
    free(fib2);
    free(temp); 
}

最初我只使用mpz_t-s,启动它们和mpz_clear() - 它们最后没有指针和malloc(),但是在计算了17(-ish)元素的幂之后导致了 Segmentation fault (core dumped) 错误 . 这是我在互联网上找到的解决方案,这几乎是我可以分配的最大数字,仍然没有任何变化,程序在同一点停止,并出现相同的错误消息 . 我也尝试使用 mp_set_memory_functions() 并创建一个自定义 mallocWrapper() 并给它GMP,但是它没有't seem to work either. Of course I' 99%肯定,它是's because I'新的GMP和相对新的使用 malloc() 所以我的代码可能让你们大多数人撕裂你的头发现在出去,我为此道歉 .

所以基本上我的问题是:我应该如何使用 malloc() 为数字获得足够的内存?

在此先感谢您的帮助!

2 回答

  • -3

    这些线:

    mpz_t *fib1;
    mpz_t *fib2;
    mpz_t *temp;
    
    fib1 = (mpz_t *) malloc(101000000 * sizeof(mpz_t));
    fib2 = (mpz_t *) malloc(101000000 * sizeof(mpz_t));
    temp = (mpz_t *) malloc(101000000 * sizeof(mpz_t));
    

    对我来说看起来很不对(你的整个源代码都很糟糕,你应该放弃它) . 看来你想分配101000000个不同的bignums,我不明白为什么你需要这么多 .

    仔细阅读GMPlib的文档和Fibonnaci numbers的定义 . 你只需要一些 mpz_t (很可能你需要不到六个 mpz_t 变量),而不是数百万个 . 在编写程序之前考虑Fibonacci的数学定义 . 请注意,如果您知道Fib(10000)和Fib(10001),使用GMPlib计算Fib(10002)很容易,那么您不再需要Fib(10000),并且可以一旦打印出Fib(10002)计算 . 请注意,您可以使用mpz_set分配GMP大整数 .

    (你真的应该在考虑数学后从头开始重写你的程序;你可以转储你现有的代码)

    不要忘记初始化每个变量,以适当地调用mpz_init .

    编译所有警告和调试信息( gcc -Wall -Wextra -g ) . Use the debuggergdb )和valgrind也许-fsanitize= debugging options

    据我所知,你的代码中甚至不需要单独显式调用 malloc (当然,内部GMPlib正在使用 malloc ) .

    (顺便说一句,作为一名学生,假设你的运动很容易,这是有帮助的)

  • 0

    如果GMP库无法处理它,请查看使用char *和算法来处理数字 . 您可以轻松地做任何GMP可以支持的事情 .

相关问题