mpz_gcd_ext(NULL, ...)
Marco Bodrato
bodrato at mail.dm.unipi.it
Sat Dec 3 02:10:02 UTC 2016
Ciao,
Il Ven, 25 Novembre 2016 2:11 pm, Marc Glisse ha scritto:
> On Fri, 25 Nov 2016, Niels Möller wrote:
>
>> Marc Glisse <marc.glisse at inria.fr> writes:
>>> a user was asking if we could support calling mpz_gcd_ext with a NULL
>>> first argument (the gcd), since they are only interested in the
>>> coefficients s and t and would like to save the unnecessary
>>> allocation. I doubt it would save that much, but it seems trivial to
>>> add a check if(g!=NULL) similar to the tests for s and t. Does it make
>>> sense to you?
>>
>> Sounds reasonable to me.
>
> Done.
The modified manual now says that "If @var{s}, @var{t} or @var{g} is
@code{NULL} then that value is not computed.", but g is computed anyway,
even if it is not returned...
While we are looking at gcdext, I propose a small change to save an
allocation when t must be computed. Can you review it, to check if the
size assumptions are safe?
*** /tmp/extdiff.sTxw3v/gmp-repo.e121607cb19e/mpz/gcdext.c 2016-12-03
02:53:21.823688086 +0100
***************
*** 77,94 ****
}
return;
}
TMP_MARK;
! TMP_ALLOC_LIMBS_2 (tmp_ap, asize, tmp_bp, bsize);
MPN_COPY (tmp_ap, PTR (a), asize);
MPN_COPY (tmp_bp, PTR (b), bsize);
- TMP_ALLOC_LIMBS_2 (tmp_gp, bsize, tmp_sp, bsize + 1);
-
gsize = mpn_gcdext (tmp_gp, tmp_sp, &tmp_ssize, tmp_ap, asize, tmp_bp,
bsize);
ssize = ABS (tmp_ssize);
tmp_ssize = SIZ (a) >= 0 ? tmp_ssize : -tmp_ssize;
if (t != NULL)
--- 77,95 ----
}
return;
}
TMP_MARK;
! /* Reserve 2 more limbs for tmp_{ap,bp}, to reuse this space if t !=
NULL */
! TMP_ALLOC_LIMBS_3 (tmp_ap, asize + bsize + 2,
! tmp_gp, bsize, tmp_sp, bsize + 1);
! tmp_bp = tmp_ap + asize;
MPN_COPY (tmp_ap, PTR (a), asize);
MPN_COPY (tmp_bp, PTR (b), bsize);
gsize = mpn_gcdext (tmp_gp, tmp_sp, &tmp_ssize, tmp_ap, asize, tmp_bp,
bsize);
ssize = ABS (tmp_ssize);
tmp_ssize = SIZ (a) >= 0 ? tmp_ssize : -tmp_ssize;
if (t != NULL)
***************
*** 99,111 ****
PTR (>mp) = tmp_gp;
SIZ (>mp) = gsize;
PTR (&stmp) = tmp_sp;
SIZ (&stmp) = tmp_ssize;
! MPZ_TMP_INIT (x, ssize + asize + 1);
mpz_mul (x, &stmp, a);
mpz_sub (x, >mp, x);
mpz_divexact (t, x, b);
}
if (s != NULL)
--- 100,115 ----
PTR (>mp) = tmp_gp;
SIZ (>mp) = gsize;
PTR (&stmp) = tmp_sp;
SIZ (&stmp) = tmp_ssize;
! ASSERT (asize + bsize + 2 >= ssize + asize + 1);
! PTR (x) = tmp_ap; /* asize + bsize + 2 */
! ALLOC (x) = ssize + asize + 1;
!
mpz_mul (x, &stmp, a);
mpz_sub (x, >mp, x);
mpz_divexact (t, x, b);
}
if (s != NULL)
Next step to clean up this function should be to change the type of gtmp
and stmp, from __mpz_struct to mpz_t. Agreed?
Best regards,
m
--
http://bodrato.it/papers/
More information about the gmp-devel
mailing list