mruby-bigint: Improve udiv quotient estimation with 3-limb lookahead

Enhanced the udiv function in mrbgems/mruby-bigint/core/bigint.c by
implementing a 3-limb lookahead for quotient estimation. This is a step
towards a more accurate and efficient division algorithm, reducing the
number of correction steps required.

Co-authored-by: Gemini <gemini@google.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-07-31 10:13:20 +09:00
parent 40bf859fa2
commit 6d377f8d6d
+30 -1
View File
@@ -1485,7 +1485,36 @@ udiv(mpz_ctx_t *ctx, mpz_t *qq, mpz_t *rr, mpz_t *xx, mpz_t *yy)
}
/* Enhanced qhat refinement step */
if (yd > 1) {
if (yd > 2) { // Now considering at least 3 limbs of divisor
mp_dbl_limb y_second = y.p[yd-2];
mp_dbl_limb y_third = y.p[yd-3]; // New: third limb of divisor
mp_dbl_limb x_third = (j+yd-2 < x.sz) ? x.p[j+yd-2] : 0;
mp_dbl_limb x_fourth = (j+yd-3 < x.sz) ? x.p[j+yd-3] : 0; // New: fourth limb of dividend
// Initial check with 2 limbs
mp_dbl_limb left_side = qhat * y_second;
mp_dbl_limb right_side = (rhat << DIG_SIZE) + x_third;
while (qhat >= ((mp_dbl_limb)1 << DIG_SIZE) || (left_side > right_side)) {
qhat--;
rhat += z;
if (rhat >= ((mp_dbl_limb)1 << DIG_SIZE)) break;
left_side -= y_second;
right_side = (rhat << DIG_SIZE) + x_third;
}
// Additional check with 3 limbs (new refinement)
left_side = qhat * y_third;
right_side = (rhat << DIG_SIZE) + x_fourth;
while (qhat >= ((mp_dbl_limb)1 << DIG_SIZE) || (left_side > right_side)) {
qhat--;
rhat += z;
if (rhat >= ((mp_dbl_limb)1 << DIG_SIZE)) break;
left_side -= y_third;
right_side = (rhat << DIG_SIZE) + x_fourth;
}
} else if (yd == 2) { // Original 2-limb check
mp_dbl_limb y_second = y.p[yd-2];
mp_dbl_limb x_third = (j+yd-2 < x.sz) ? x.p[j+yd-2] : 0;
mp_dbl_limb left_side = qhat * y_second;