2010-04-29 76 views
0

嘿,我試圖轉換一個我寫的函數來生成一個long數組,它將Pascal的三角形代入一個返回mpz_t數組的函數中。但是用下面的代碼:用mpz_t製作pascal的三角形

mpz_t* make_triangle(int rows, int* count) { 
//compute triangle size using 1 + 2 + 3 + ... n = n(n + 1)/2 
*count = (rows * (rows + 1))/2; 
mpz_t* triangle = malloc((*count) * sizeof(mpz_t)); 

//fill in first two rows 
mpz_t one; 
mpz_init(one); 
mpz_set_si(one, 1); 
triangle[0] = one; triangle[1] = one; triangle[2] = one; 

int nums_to_fill = 1; 
int position = 3; 
int last_row_pos; 
int r, i; 
for(r = 3; r <= rows; r++) { 
    //left most side 
    triangle[position] = one; 
    position++; 

    //inner numbers 
    mpz_t new_num; 
    mpz_init(new_num); 
    last_row_pos = ((r - 1) * (r - 2))/2; 
    for(i = 0; i < nums_to_fill; i++) { 
     mpz_add(new_num, triangle[last_row_pos + i], triangle[last_row_pos + i + 1]); 
     triangle[position] = new_num; 
     mpz_clear(new_num); 
     position++; 
    } 
    nums_to_fill++; 

    //right most side 
    triangle[position] = one; 
    position++; 
} 

return triangle; 
} 

遇到錯誤說:不兼容的類型中的分配對於其中在三角形的位置被設定的所有行(即:三角形[位置] =一個)。

有誰知道我可能會做錯什麼?

回答

3

mpz_t被定義爲長度爲1的struct __mpz_struct的數組,其阻止賦值。這是因爲普通的C賦值是淺拷貝,而各種gmp數字類型存儲指向需要深拷貝的"limbs"數組的指針。您需要使用mpz_setmpz_init_set(或甚至mpz_init_set_si)來分配MP整數,請確保在使用前者之前初始化目標。

此外,您應該每mpz_init最多撥打mpz_clear一次(它們就像malloc並在這方面是免費的,出於同樣的原因)。通過在內部循環中的外部循環mpz_clear(new_num)中調用mpz_init(new_nom),您引入了一個錯誤,當您檢查make_triangle的結果時,這將顯而易見。但是,你甚至不需要new_num;初始化triangle的下一個元素,並將其用作mpz_add的目標。

mpz_init(triangle[position]); 
    mpz_add(triangle[position++], triangle[last_row_pos + i], triangle[last_row_pos + i + 1]); 

小數值優化:你可以使用加法和減法,而不是兩個減法,乘法和除法更新last_row_pos。看看你是否可以弄清楚如何。