mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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:
@@ -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 */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user