Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d996d64

Browse files
committed
Simplify the inner loop of numeric division in div_var().
In the standard numeric division algorithm, the inner loop multiplies the divisor by the next quotient digit and subtracts that from the working dividend. As suggested by the original code comment, the separate "carry" and "borrow" variables (from the multiplication and subtraction steps respectively) can be folded together into a single variable. Doing so significantly improves performance, as well as simplifying the code. Dean Rasheed, reviewed by Tom Lane. Discussion: https://postgr.es/m/CAEZATCVwsBi-ND-t82Cuuh1=8ee6jdOpzsmGN+CUZB6yjLg9jw@mail.gmail.com
1 parent e3d41d0 commit d996d64

File tree

1 file changed

+15
-21
lines changed

1 file changed

+15
-21
lines changed

src/backend/utils/adt/numeric.c

+15-21
Original file line numberDiff line numberDiff line change
@@ -8605,31 +8605,25 @@ div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
86058605
/* As above, need do nothing more when quotient digit is 0 */
86068606
if (qhat > 0)
86078607
{
8608+
NumericDigit *dividend_j = &dividend[j];
8609+
86088610
/*
86098611
* Multiply the divisor by qhat, and subtract that from the
8610-
* working dividend. "carry" tracks the multiplication,
8611-
* "borrow" the subtraction (could we fold these together?)
8612+
* working dividend. The multiplication and subtraction are
8613+
* folded together here, noting that qhat <= NBASE (since it
8614+
* might be one too large), and so the intermediate result
8615+
* "tmp_result" is in the range [-NBASE^2, NBASE - 1], and
8616+
* "borrow" is in the range [0, NBASE].
86128617
*/
8613-
carry = 0;
86148618
borrow = 0;
86158619
for (i = var2ndigits; i >= 0; i--)
86168620
{
8617-
carry += divisor[i] * qhat;
8618-
borrow -= carry % NBASE;
8619-
carry = carry / NBASE;
8620-
borrow += dividend[j + i];
8621-
if (borrow < 0)
8622-
{
8623-
dividend[j + i] = borrow + NBASE;
8624-
borrow = -1;
8625-
}
8626-
else
8627-
{
8628-
dividend[j + i] = borrow;
8629-
borrow = 0;
8630-
}
8621+
int tmp_result;
8622+
8623+
tmp_result = dividend_j[i] - borrow - divisor[i] * qhat;
8624+
borrow = (NBASE - 1 - tmp_result) / NBASE;
8625+
dividend_j[i] = tmp_result + borrow * NBASE;
86318626
}
8632-
Assert(carry == 0);
86338627

86348628
/*
86358629
* If we got a borrow out of the top dividend digit, then
@@ -8645,15 +8639,15 @@ div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
86458639
carry = 0;
86468640
for (i = var2ndigits; i >= 0; i--)
86478641
{
8648-
carry += dividend[j + i] + divisor[i];
8642+
carry += dividend_j[i] + divisor[i];
86498643
if (carry >= NBASE)
86508644
{
8651-
dividend[j + i] = carry - NBASE;
8645+
dividend_j[i] = carry - NBASE;
86528646
carry = 1;
86538647
}
86548648
else
86558649
{
8656-
dividend[j + i] = carry;
8650+
dividend_j[i] = carry;
86578651
carry = 0;
86588652
}
86598653
}

0 commit comments

Comments
 (0)