用 mpz_t 制作帕斯卡三角形

发布于 2024-08-30 23:54:47 字数 1122 浏览 6 评论 0原文

嘿,我正在尝试将我编写的用于生成表示 Pascal 三角形的 long 数组的函数转换为返回 mpz_t 数组的函数。但是,使用以下代码:

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;
}

我收到错误消息:在设置三角形位置的所有行的赋值中类型不兼容(即:triangle[position] = one;)。

有谁知道我可能做错了什么?

Hey, I'm trying to convert a function I wrote to generate an array of longs that respresents Pascal's triangles into a function that returns an array of mpz_t's. However with the following code:

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;
}

I'm getting errors saying: incompatible types in assignment for all lines where a position in the triangle is being set (i.e.: triangle[position] = one;).

Does anyone know what I might be doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笨死的猪 2024-09-06 23:54:47

mpz_t 被定义为 struct __mpz_struct 长度为 1 的数组,这会阻止赋值。这样做是因为正常的 C 赋值是浅拷贝,并且各种 gmp 数字类型存储指向 数组的指针需要深度复制的“肢体”。您需要使用 mpz_set 或 < a href="http://gmplib.org/manual/Simultaneous-Integer-Init-_0026-Assign.html#Simultaneous-Integer-Init-_0026-Assign" rel="nofollow noreferrer">mpz_init_set (甚至 mpz_init_set_si)来分配 MP 整数,确保在使用前者之前初始化目标。

另外,您应该为每个 mpz_init 最多调用一次 mpz_clear (在这方面它们类似于 malloc 和 free,并且出于相同的原因)。通过在外部循环中调用 mpz_init(new_nom) 在内循环中的 mpz_clear(new_num) ,您将引入一个错误,当您检查 mpz_clear(new_num) 的结果时,该错误将会很明显。代码>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,而不是使用两个减法(乘法和除法)。看看你是否能弄清楚如何做。

mpz_t is define as an array of length 1 of struct __mpz_struct, which prevents assignment. This is done because normal C assignment is a shallow copy and the various gmp numeric types store pointers to arrays of "limbs" that need to be deep copied. You need to use mpz_set or mpz_init_set (or even mpz_init_set_si) to assign MP integers, making sure you initialize the destination before using the former.

Also, you should call mpz_clear at most once for every mpz_init (they're like malloc and free in this regard, and for the same reasons). By calling mpz_init(new_nom) in the outer loop mpz_clear(new_num) in the inner loop, you're introducing a bug which will be evident when you examine the results of make_triangle. However, you don't even need new_num; initialize the next element of triangle and use it as the destination of mpz_add.

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

Small numeric optimization: you can update last_row_pos using an addition and subtraction rather than two subtractions, a multiplication and division. See if you can figure out how.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文