2017-10-06 84 views
1

我遇到了一個返回大於C可以處理的nunber的代碼的麻煩。我安裝了GMP庫,但所有在互聯網上找到的教程都無法使其工作。這是GMP庫函數的代碼。目前,即時嘗試通過閱讀本網站的手冊使其工作:https://gmplib.org/manual/ 該程序簡單地崩潰,我認爲這是因爲我從Int函數返回一個mpz_t整數。我該如何解決這個問題?在C中使用GMP的大數字

編輯:我編輯了Antoine說的代碼,現在我沒有錯誤,但程序崩潰時,我運行它。

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

typedef struct Vector{ 
int *v; 
}vetor; 

int nextPow2(int n); 
int Multiplicacao(mpz_t r, int *x, int *y, int n); 

int main(){ 

int n = 100; 
vetor *x = malloc(sizeof(vetor)); 
vetor *y = malloc(sizeof(vetor)); 

srand((unsigned)time(NULL)); 
int i; 

int c = 0; 
i=0; 
c = nextPow2(n); 

x->v = malloc(sizeof(int)*c); 
y->v = malloc(sizeof(int)*c); 

for(i=0; i<c; i++){ 
    x->v[i] = 0; 
    y->v[i] = 0; 
} 

int d = c-n; 
i = c; 
while(i>=d){ 
    x->v[i] = rand()%2; 
    y->v[i] = rand()%2; 
    i--; 
} 

printf("\n Vetor X\n"); 

for(i=0; i<c; i++){ 
    printf("%i", x->v[i]); 
} 

printf("\n Vetor Y\n"); 

for(i=0; i<c; i++){ 
    printf("%i", y->v[i]); 
} 

mpz_t r; 
mpz_inits(r); 

mpz_set(r, Multiplicacao(r, x->v, y->v, c)); 

printf("\n\n RESULTADO \n\n"); 
gmp_printf ("%Zd\n", r); 
mpz_clear(r); 

return 0; 
} 

int Multiplicacao(mpz_t r, int *x, int *y, int n){ 
if(n==1) 
    return x[0]*y[0]; 
else{ 
    vetor *Xe = malloc(sizeof(vetor)); 
    vetor *Xd = malloc(sizeof(vetor)); 
    vetor *Ye = malloc(sizeof(vetor)); 
    vetor *Yd = malloc(sizeof(vetor)); 
    int j; 
    Xe->v = malloc(sizeof(int)*n/2); 
    Xd->v = malloc(sizeof(int)*n/2); 
    Ye->v = malloc(sizeof(int)*n/2); 
    Yd->v = malloc(sizeof(int)*n/2); 

    for(j=0; j<n/2; j++){ 
     Xe->v[j]=x[j]; 
     Ye->v[j]=y[j]; 
    } 
    int k=0; 
    for(j=n/2; j<n; j++){ 
     Xd->v[k]=x[j]; 
     Yd->v[k]=y[j]; 
     k++; 
    } 

    mpz_t p1, p2, p3, p4, a, b; 
    mpz_inits(p1, p2, p3, p4, a, b); 

    mpz_ui_pow_ui(a, 2, n); 
    mpz_ui_pow_ui(b, 2, n/2); 


    mpz_set(p1, Multiplicacao(r, Xe->v, Ye->v, n/2)); 
    mpz_set(p2, Multiplicacao(r, Xe->v, Yd->v, n/2)); 
    mpz_set(p3, Multiplicacao(r, Xd->v, Ye->v, n/2)); 
    mpz_set(p4, Multiplicacao(r, Xd->v, Yd->v, n/2)); 

    mpz_mul(p1, p1, a); 
    mpz_mul(p2, p2, b); 
    mpz_mul(p3, p3, b); 

    mpz_add(p1, p1, p2); 
    mpz_add(p3, p3, p4); 
    mpz_add(p1, p1, p3); 

    return p1; 
} 
} 

int nextPow2(int n) 
{ 
if (n <= 1) return n; 
double d = n-1; 
return 1 << ((((int*)&d)[1]>>20)-1022); 
} 
+1

問題是什麼? –

+0

你可能想考慮使用'free()'。 – cdarke

+0

問題是,我如何使一個int函數返回一個mpz_t值? –

回答

1

返回mpz_t是不好的做法。你應該有你的函數採取的第一個參數mpz_t其結果爲存儲:

void func (mpz_t result, ...) 
{ 
    ... 
    mpz_set (result, ...); 
} 

,並調用它像這樣:

mpz_t result; 
mpz_init (result); 

func (result, ...); 
gmp_printf ("%Zd\n", result); 

mpz_clear (result); 

除此之外打開警告和閱讀GMP手冊小心。您需要閱讀您使用的每個功能的完整文檔。特別注意功能簽名。例如,您應該使用mpz_ui_pow_ui而不是mpz_pow_ui。實際上,在您的代碼中使用GMP功能是錯誤的。

+0

我會試試看。謝謝 –