2010-04-29 80 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。看看你是否可以弄清楚如何。