-2

when i enter some values i get the answer but other values no,the system stay blocked

int pgcdfon(mpz_t a, mpz_t b, mpz_t *x, mpz_t *y) {
    if (mpz_cmp_ui(a, 0) == 0) {
        mpz_set_ui(*x, 0);
        mpz_set_ui(*y, 1);
        return b;
    }
    mpz_t x1, y1, res, h;
    mpz_init(x1);
    mpz_init(y1);
    mpz_init(res);
    mpz_t o;
    mpz_init(o);
    mpz_init(h);
    mpz_mod(res, b, a);
    int pgcd = pgcdfon(res, a, &x1, &y1);
    mpz_div(o, b, a);
    mpz_mul(h, o, x1);
    mpz_sub(*x, y1, h);
    mpz_set(*y, x1);
    return pgcd;
}

void main() {
    mpz_t x, y, q, w, g;
    mpz_init(x);
    mpz_init(y);
    mpz_init(q);
    mpz_init(w);
    mpz_init(g);
    gmp_printf("donner q \n ");
    gmp_scanf("%Zd", &q);
    gmp_printf("donner w \n");
    gmp_scanf("%Zd", &w);
    mpz_set(g, (pgcdfon(q, w, &x, &y)));
    gmp_printf("\n\n pgcd  de (%Zd, %Zd) = %Zd  \n\n", q, w, g);
}
abelenky
  • 63,815
  • 23
  • 109
  • 159
Zineb
  • 9
  • 4
  • 3
    What values? What are the expected inputs and outputs? – Federico klez Culloca Oct 22 '19 at 13:37
  • 1
    I just tried compiling this, and got 4 warnings. Try to fix those, at least the return type warning. (`pgcdfon`is defined as returning `int`, but you're actually returning an `mpz_t`) – hager Oct 22 '19 at 13:47
  • @FedericoklezCulloca i'm new at gmp so i tried to change int into mpz_t but it's incorrect ,so i really don't know what to do ,i added clear at the end but it's the same problem – Zineb Oct 22 '19 at 13:53
  • The C++ interface (gmpxx.h, type mpz_class) is much easier to use for beginners who have no idea what they are doing. – Marc Glisse Oct 22 '19 at 17:37

1 Answers1

1

The type mpz_t is a (disguised) array type and hence cannot be returned from a function. You have to change the prototype of your function to return the value in an out parameter, instead of returning it. This means, a function like

mpz_t myfun (...) {
     mpz_t ret;
     mpz_init(ret);

     // fill ret with someting

     return ret;
}

cannot work, but has to be rewritten as:

void myfun (..., mpz_t *out) {
     mpz_t ret;
     mpz_init(ret);

     // fill ret with stuff
     mpz_init(*out); // if not initialized by caller
     mpz_set(*out, ret);
}

This technique applied to your function yields

void pgcdfon(mpz_t a, mpz_t b, mpz_t *x, mpz_t *y, mpz_t *ret) {
    if (mpz_cmp_ui(a, 0) == 0) {
        mpz_set_ui(*x, 0);
        mpz_set_ui(*y, 1);
        mpz_init(*ret);
        mpz_set(*ret, b);
        return;
    }
    mpz_t x1, y1, res, h;
    mpz_init(x1);
    mpz_init(y1);
    mpz_init(res);
    mpz_t o;
    mpz_init(o);
    mpz_init(h);
    mpz_mod(res, b, a);
    mpz_t pgcd;
    pgcdfon(res, a, &x1, &y1, &pgcd);
    mpz_div(o, b, a);
    mpz_mul(h, o, x1);
    mpz_sub(*x, y1, h);
    mpz_set(*y, x1);
    mpz_init(*ret);
    mpz_set(*ret, pgcd);
}

int main() {
    mpz_t x, y, q, w, g;
    mpz_init(x);
    mpz_init(y);
    mpz_init(q);
    mpz_init(w);
    mpz_init(g);
    gmp_printf("donner q \n ");
    gmp_scanf("%Zd", &q);
    gmp_printf("donner w \n");
    gmp_scanf("%Zd", &w);
    pgcdfon(q, w, &x, &y, &g);
    gmp_printf("\n\n pgcd  de (%Zd, %Zd) = %Zd  \n\n", q, w, g);
}

which should work as you expect.

Ctx
  • 18,090
  • 24
  • 36
  • 51
  • 1
    There is no reason to use `mpz_t*` for the arguments, you can just pass them as `mpz_t`. If you want to distinguish the input parameters, you could pass those as `const mpz_t`. – Marc Glisse Oct 22 '19 at 20:03
  • @MarcGlisse if * doesn't exist ,it might give me faulse results because the values won't be exchanged when i use the function in main – Zineb Oct 22 '19 at 20:22
  • 1
    @Zineb If you check the doc, you will see `void mpz_add (mpz_t rop, const mpz_t op1, const mpz_t op2)` where `rop` is the output. Is that hint sufficient for you? – Marc Glisse Oct 22 '19 at 20:29
  • @Ctx i need a help how can i translate this into GMP ? this is a function in c ,i need to set this variables.void Bezout(int rkm2,int rkm1,int ukm1=0,int vkm1=1,int ukm2=1,int vkm2=0) – Zineb Oct 28 '19 at 21:55