/* Botch: Should this be handled at all? Rely on callers? */ if (!dividend_size) return0;
/* If multiplication is much faster than division, and the *dividendislarge,pre-invertthedivisor,anduse *onlymultiplicationsintheinnerloop. * *Thistestshouldberead: *Doesiteverhelptouseudiv_qrnnd_preinv? *&&Doeswhatwesavecompensatefortheinversionoverhead?
*/ if (UDIV_TIME > (2 * UMUL_TIME + 6)
&& (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) { int normalization_steps;
normalization_steps = count_leading_zeros(divisor_limb); if (normalization_steps) {
mpi_limb_t divisor_limb_inverted;
switch (dsize) { case0: /* We are asked to divide by zero, so go ahead and do it! (To make
the compiler not remove this statement, return the value.) */ /* *existingclientsofthisfunctionhavebeenmodified *nottocallitwithdsize==0,sothisshouldnothappen
*/ return1 / dsize;
for (i = qextra_limbs + nsize - 2 - 1; i >= 0; i--) {
mpi_limb_t q;
mpi_limb_t r;
if (i >= qextra_limbs)
np--; else
np[0] = 0;
if (n1 == d1) { /* Q should be either 111..111 or 111..110. Need special *treatmentofthisrarecaseasnormaldivisionwould
* give overflow. */
q = ~(mpi_limb_t) 0;
n2 = np[0];
q_test: if (n1 > r || (n1 == r && n0 > n2)) { /* The estimated Q was too large. */
q--;
sub_ddmmss(n1, n0, n1, n0, 0, d0);
r += d1; if (r >= d1) /* If not carry, test Q again. */ goto q_test;
}
if (n0 == dX) { /* This might over-estimate q, but it's probably not worth
* the extra code here to find out. */
q = ~(mpi_limb_t) 0;
} else {
mpi_limb_t r;
while (n1 > r
|| (n1 == r
&& n0 > np[dsize - 2])) {
q--;
r += dX; if (r < dX) /* I.e. "carry in previous addition?" */ break;
n1 -= n0 < d1;
n0 -= d1;
}
}
/* Possible optimization: We already have (q * n0) and (1 * n1) *afterthecalculationofq.Takingadvantageofthat,we
* could make this loop make two iterations less. */
cy_limb = mpihelp_submul_1(np, dp, dsize, q);
/* If multiplication is much faster than division, and the *dividendislarge,pre-invertthedivisor,anduse *onlymultiplicationsintheinnerloop. * *Thistestshouldberead: *Doesiteverhelptouseudiv_qrnnd_preinv? *&&Doeswhatwesavecompensatefortheinversionoverhead?
*/ if (UDIV_TIME > (2 * UMUL_TIME + 6)
&& (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) { int normalization_steps;
normalization_steps = count_leading_zeros(divisor_limb); if (normalization_steps) {
mpi_limb_t divisor_limb_inverted;
divisor_limb <<= normalization_steps;
/* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The *resultisa(N+1)-bitapproximationto1/DIVISOR_LIMB,withthe *mostsignificantbit(withweight2**N)implicit.
*/ /* Special case for DIVISOR_LIMB == 100...000. */ if (!(divisor_limb << 1))
divisor_limb_inverted = ~(mpi_limb_t)0; else
udiv_qrnnd(divisor_limb_inverted, dummy,
-divisor_limb, 0, divisor_limb);
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.