mruby-bigint: extract core addition algorithm to eliminate duplication

Extract multi-limb addition algorithm from uadd() and uadd_pool() into
shared uadd_core() helper function. Both functions now use the same
core addition logic with carry propagation, eliminating duplication
and ensuring consistent behavior.

Benefits:
- Eliminates ~13 lines of duplicated addition algorithm code
- Single source of truth for multi-limb addition with carry handling
- Reduces maintenance burden for future optimizations
- Maintains all existing functionality and performance

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-07-25 12:11:00 +09:00
parent 906b0aece7
commit 2e45af37a8
+30 -27
View File
@@ -337,6 +337,32 @@ trim(mpz_t *x)
}
/* Core addition algorithm - extracted from uadd/uadd_pool duplication */
static void
uadd_core(mpz_t *z, mpz_t *x, mpz_t *y)
{
/* Core multi-limb addition with carry propagation */
mp_dbl_limb c = 0;
size_t i;
/* Add overlapping limbs from both operands */
for (i = 0; i < x->sz; i++) {
c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];
z->p[i] = LOW(c);
c >>= DIG_SIZE;
}
/* Add remaining limbs from larger operand */
for (; i < y->sz; i++) {
c += y->p[i];
z->p[i] = LOW(c);
c >>= DIG_SIZE;
}
/* Store final carry */
z->p[y->sz] = (mp_limb)c;
}
/* z = x + y, without regard for sign */
static void
uadd(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y)
@@ -349,19 +375,8 @@ uadd(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y)
/* now y->sz >= x->sz */
mpz_realloc(mrb, z, y->sz+1);
mp_dbl_limb c = 0;
size_t i;
for (i=0; i<x->sz; i++) {
c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];
z->p[i] = LOW(c);
c >>= DIG_SIZE;
}
for (;i<y->sz; i++) {
c += y->p[i];
z->p[i] = LOW(c);
c >>= DIG_SIZE;
}
z->p[y->sz] = (mp_limb)c;
/* Use core addition algorithm */
uadd_core(z, x, y);
}
/* Pool-based unsigned addition - uses stack memory for result */
@@ -384,20 +399,8 @@ uadd_pool(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y, mpz_pool_t *pool)
/* Try to allocate in pool */
MPZ_POOL_ALLOC(mrb, *z, pool, result_size);
/* Perform addition using pool memory */
mp_dbl_limb c = 0;
size_t i;
for (i=0; i<x->sz; i++) {
c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];
z->p[i] = LOW(c);
c >>= DIG_SIZE;
}
for (;i<y->sz; i++) {
c += y->p[i];
z->p[i] = LOW(c);
c >>= DIG_SIZE;
}
z->p[y->sz] = (mp_limb)c;
/* Use core addition algorithm */
uadd_core(z, x, y);
return 1; /* Success - used pool memory */
}