diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index dcdc5cf..03a646b 100644
*** a/src/backend/utils/adt/numeric.c
--- b/src/backend/utils/adt/numeric.c
*************** div_var_fast(NumericVar *var1, NumericVa
*** 6186,6192 ****
  	double		fdividend,
  				fdivisor,
  				fdivisorinverse,
! 				fquotient;
  	int			qi;
  	int			i;
  
--- 6186,6193 ----
  	double		fdividend,
  				fdivisor,
  				fdivisorinverse,
! 				fquotient,
! 				outercarry;
  	int			qi;
  	int			i;
  
*************** div_var_fast(NumericVar *var1, NumericVa
*** 6274,6289 ****
  	 * To avoid overflow in maxdiv itself, it represents the max absolute
  	 * value divided by NBASE-1, ie, at the top of the loop it is known that
  	 * no div[] entry has an absolute value exceeding maxdiv * (NBASE-1).
  	 */
  	maxdiv = 1;
  
  	/*
! 	 * Outer loop computes next quotient digit, which will go into div[qi]
  	 */
  	for (qi = 0; qi < div_ndigits; qi++)
  	{
  		/* Approximate the current dividend value */
! 		fdividend = (double) div[qi];
  		for (i = 1; i < 4; i++)
  		{
  			fdividend *= NBASE;
--- 6275,6297 ----
  	 * To avoid overflow in maxdiv itself, it represents the max absolute
  	 * value divided by NBASE-1, ie, at the top of the loop it is known that
  	 * no div[] entry has an absolute value exceeding maxdiv * (NBASE-1).
+ 	 *
+ 	 * Note that maxdiv only includes digit positions that are still part of
+ 	 * the dividend, ie, strictly speaking the above holds only for div[i]
+ 	 * where i >= qi, at the top of the loop.
  	 */
  	maxdiv = 1;
  
  	/*
! 	 * Outer loop computes next quotient digit, which will go into div[qi].
! 	 * "outercarry" represents high-order dividend digits carried across
! 	 * iterations.
  	 */
+ 	outercarry = 0;
  	for (qi = 0; qi < div_ndigits; qi++)
  	{
  		/* Approximate the current dividend value */
! 		fdividend = outercarry * NBASE + (double) div[qi];
  		for (i = 1; i < 4; i++)
  		{
  			fdividend *= NBASE;
*************** div_var_fast(NumericVar *var1, NumericVa
*** 6320,6340 ****
  						carry = 0;
  					div[i] = newdig;
  				}
! 				newdig = div[qi] + carry;
! 				div[qi] = newdig;
  
  				/*
  				 * All the div[] digits except possibly div[qi] are now in the
! 				 * range 0..NBASE-1.
  				 */
! 				maxdiv = Abs(newdig) / (NBASE - 1);
! 				maxdiv = Max(maxdiv, 1);
  
  				/*
  				 * Recompute the quotient digit since new info may have
  				 * propagated into the top four dividend digits
  				 */
! 				fdividend = (double) div[qi];
  				for (i = 1; i < 4; i++)
  				{
  					fdividend *= NBASE;
--- 6328,6347 ----
  						carry = 0;
  					div[i] = newdig;
  				}
! 				div[qi] += carry;
  
  				/*
  				 * All the div[] digits except possibly div[qi] are now in the
! 				 * range 0..NBASE-1; and we don't care about including div[qi]
! 				 * anymore, so we can reset maxdiv to 1.
  				 */
! 				maxdiv = 1;
  
  				/*
  				 * Recompute the quotient digit since new info may have
  				 * propagated into the top four dividend digits
  				 */
! 				fdividend = outercarry * NBASE + (double) div[qi];
  				for (i = 1; i < 4; i++)
  				{
  					fdividend *= NBASE;
*************** div_var_fast(NumericVar *var1, NumericVa
*** 6360,6370 ****
  
  		/*
  		 * The dividend digit we are about to replace might still be nonzero.
! 		 * Fold it into the next digit position.  We don't need to worry about
! 		 * overflow here since this should nearly cancel with the subtraction
! 		 * of the divisor.
  		 */
! 		div[qi + 1] += div[qi] * NBASE;
  
  		div[qi] = qdigit;
  	}
--- 6367,6382 ----
  
  		/*
  		 * The dividend digit we are about to replace might still be nonzero.
! 		 * Carry it forward to future division steps in "outercarry".
! 		 *
! 		 * Although it might appear that outercarry would soon grow large
! 		 * enough to lose precision, this is not actually possible because
! 		 * each divisor-subtraction step will drive the accumulated value
! 		 * towards zero.  We could probably store it in an int without
! 		 * overflow problems, but since the value is only used in floating
! 		 * calculations, we might as well store it as a double.
  		 */
! 		outercarry = outercarry * NBASE + (double) div[qi];
  
  		div[qi] = qdigit;
  	}
*************** div_var_fast(NumericVar *var1, NumericVa
*** 6372,6378 ****
  	/*
  	 * Approximate and store the last quotient digit (div[div_ndigits])
  	 */
! 	fdividend = (double) div[qi];
  	for (i = 1; i < 4; i++)
  		fdividend *= NBASE;
  	fquotient = fdividend * fdivisorinverse;
--- 6384,6390 ----
  	/*
  	 * Approximate and store the last quotient digit (div[div_ndigits])
  	 */
! 	fdividend = outercarry * NBASE + (double) div[qi];
  	for (i = 1; i < 4; i++)
  		fdividend *= NBASE;
  	fquotient = fdividend * fdivisorinverse;
