YoushouldhavereceivedcopiesoftheGNUGeneralPublicLicenseandthe GNULesserGeneralPublicLicensealongwiththeGNUMPLibrary.Ifnot,
see https://www.gnu.org/licenses/. */
/* Reduces a,b until |a-b| fits in n/2 + 1 limbs. Constructs matrix M withelementsofsizeatmost(n+1)/2-1.Returnsnewsizeofa,
b, or zero if no reduction is possible. */
mp_size_t
mpn_hgcd (mp_ptr ap, mp_ptr bp, mp_size_t n, struct hgcd_matrix *M, mp_ptr tp)
{
mp_size_t s = n/2 + 1;
mp_size_t nn; int success = 0;
if (n <= s) /* Happens when n <= 2, a fairly uninteresting case but exercised
by the random inputs of the testsuite. */ return0;
ASSERT ((ap[n-1] | bp[n-1]) > 0);
ASSERT ((n+1)/2 - 1 < M->alloc);
if (ABOVE_THRESHOLD (n, HGCD_THRESHOLD))
{
mp_size_t n2 = (3*n)/4 + 1;
mp_size_t p = n/2;
nn = mpn_hgcd_reduce (M, ap, bp, n, p, tp); if (nn)
{
n = nn;
success = 1;
}
/* NOTE: It appears this loop never runs more than once (at
least when not recursing to hgcd_appr). */ while (n > n2)
{ /* Needs n + 1 storage */
nn = mpn_hgcd_step (n, ap, bp, s, M, tp); if (!nn) return success ? n : 0;
n = nn;
success = 1;
}
if (n > s + 2)
{ struct hgcd_matrix M1;
mp_size_t scratch;
p = 2*s - n + 1;
scratch = MPN_HGCD_MATRIX_INIT_ITCH (n-p);
mpn_hgcd_matrix_init(&M1, n - p, tp);
/* FIXME: Should use hgcd_reduce, but that may require more
scratch space, which requires review. */
nn = mpn_hgcd (ap + p, bp + p, n - p, &M1, tp + scratch); if (nn > 0)
{ /* We always have max(M) > 2^{-(GMP_NUMB_BITS + 1)} max(M1) */
ASSERT (M->n + 2 >= M1.n);
/* Furthermore, assume M ends with a quotient (1, q; 0, 1), theneitherqorq+1isacorrectquotient,andM1will startwitheither(1,0;1,1)or(2,1;1,1).This rulesoutthecasethatthesizeofM*M1ismuch
smaller than the expected M->n + M1->n. */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.