YoushouldhavereceivedcopiesoftheGNUGeneralPublicLicenseandthe GNULesserGeneralPublicLicensealongwiththeGNUMPLibrary.Ifnot,
see https://www.gnu.org/licenses/. */
/* compute {s,3m-1} = {a,3m-1} + {a+m,3m-1} and error terms e0, e1, e2, e3 */
cy = mpn_add_err1_n (s, ap, ap + m, &e0l, bp + m, m - 1, 0);
cy = mpn_add_err2_n (s + m - 1, ap + m - 1, ap + 2*m - 1, &e1l,
bp + m, bp, m, cy);
mpn_add_err1_n (s + 2*m - 1, ap + 2*m - 1, ap + 3*m - 1, &e3l, bp, m, cy);
/* compute t = (-1)^neg * ({b,m} - {b+m,m}) and error terms e4, e5 */ if (mpn_cmp (bp + m, bp, m) < 0)
{
ASSERT_NOCARRY (mpn_sub_err2_n (t, bp, bp + m, &e4l,
ap + m - 1, ap + 2*m - 1, m, 0));
neg = 1;
} else
{
ASSERT_NOCARRY (mpn_sub_err2_n (t, bp + m, bp, &e4l,
ap + m - 1, ap + 2*m - 1, m, 0));
neg = 0;
}
if (m < MULMID_TOOM42_THRESHOLD)
{ /* A + B */
mpn_mulmid_basecase (p0, s, 2*m - 1, bp + m, m); /* accumulate high limbs of p0 into e1 */
ADDC_LIMB (cy, e1l, e1l, p0[m]);
e1h += p0[m + 1] + cy; /* (-1)^neg * (B - C) (overwrites first m limbs of s) */
mpn_mulmid_basecase (p1, ap + m, 2*m - 1, t, m); /* C + D (overwrites t) */
mpn_mulmid_basecase (p2, s + m, 2*m - 1, bp, m);
} else
{ /* as above, but use toom42 instead */
mpn_toom42_mulmid (p0, s, bp + m, m, next_scratch);
ADDC_LIMB (cy, e1l, e1l, p0[m]);
e1h += p0[m + 1] + cy;
mpn_toom42_mulmid (p1, ap + m, t, m, next_scratch);
mpn_toom42_mulmid (p2, s + m, bp, m, next_scratch);
}
/* adjustment if p1 ends up negative */
cy = (p1[m + 1] >> (GMP_NUMB_BITS - 1));
/* add (-1)^neg * (p1 - B^m * p1) to output */ if (neg)
{
mpn_sub_1 (rp + m + 2, rp + m + 2, m, cy);
mpn_add (rp, rp, 2*m + 2, p1, m + 2); /* A + C */
mpn_sub_n (rp + m, rp + m, p1, m + 2); /* B + D */
} else
{
mpn_add_1 (rp + m + 2, rp + m + 2, m, cy);
mpn_sub (rp, rp, 2*m + 2, p1, m + 2); /* A + C */
mpn_add_n (rp + m, rp + m, p1, m + 2); /* B + D */
}
/* odd row and diagonal */ if (n & 1)
{ /* ProductsmarkedEarealreadydone.WeneedtodoproductsmarkedO.
/* first row of O's */
cy = mpn_addmul_1 (rp, ap - 1, n, bp[n - 1]);
ADDC_LIMB (rp[n + 1], rp[n], rp[n], cy);
/* O's on diagonal */ /* FIXME: should probably define an interface "mpn_mulmid_diag_1" thatcanhandlethesumbelow.Currentlywe'rerelyingon mulmid_basecasebeingprettyfastforadiagonalsumlikethis, whichistrueatleastfortheK8asmversion,butsurelyfalse
for the generic version. */
mpn_mulmid_basecase (e, ap + n - 1, n - 1, bp, n - 1);
mpn_add_n (rp + n - 1, rp + n - 1, e, 3);
}
}
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.