diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
new file mode 100644
index 5510a20..5999a19
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -1909,7 +1909,7 @@ width_bucket_numeric(PG_FUNCTION_ARGS)
 
 /*
  * 'operand' is inside the bucket range, so determine the correct
- * bucket for it to go. The calculations performed by this function
+ * bucket for it to go in. The calculations performed by this function
  * are derived directly from the SQL2003 spec. Note however that we
  * multiply by count before dividing, to avoid unnecessary roundoff error.
  */
@@ -1928,32 +1928,26 @@ compute_bucket(Numeric operand, Numeric
 
 	if (!reversed_bounds)
 	{
+		/* bound1 <= operand < bound2 */
 		sub_var(&operand_var, &bound1_var, &operand_var);
 		sub_var(&bound2_var, &bound1_var, &bound2_var);
 	}
 	else
 	{
+		/* bound2 < operand <= bound1 */
 		sub_var(&bound1_var, &operand_var, &operand_var);
 		sub_var(&bound1_var, &bound2_var, &bound2_var);
 	}
 
-	mul_var(&operand_var, count_var, &operand_var,
-			operand_var.dscale + count_var->dscale);
-	div_var(&operand_var, &bound2_var, result_var,
-			select_div_scale(&operand_var, &bound2_var), true);
-
 	/*
-	 * Roundoff in the division could give us a quotient exactly equal to
-	 * "count", which is too large.  Clamp so that we do not emit a result
-	 * larger than "count".
+	 * Now we have 0 <= operand < bound2.  The required bucket index is given
+	 * by (operand * count) / bound2 + 1, using "floor division" -- i.e.,
+	 * dividing to zero decimal places with truncation.
 	 */
-	if (cmp_var(result_var, count_var) >= 0)
-		set_var_from_var(count_var, result_var);
-	else
-	{
-		add_var(result_var, &const_one, result_var);
-		floor_var(result_var, result_var);
-	}
+	mul_var(&operand_var, count_var, &operand_var,
+			operand_var.dscale + count_var->dscale);
+	div_var(&operand_var, &bound2_var, result_var, 0, false);
+	add_var(result_var, &const_one, result_var);
 
 	free_var(&bound1_var);
 	free_var(&bound2_var);
