GitHub

File tree

  • mrbgems/mruby-bigint/core

Original file line numberDiff line numberDiff line change

@@ -354,10 +354,11 @@ uadd(mpz_t *z, mpz_t *x, mpz_t *y)

354354

/* Core multi-limb addition with carry propagation */

355355

mp_dbl_limb c = 0;

356356

size_t i;

357+

size_t min_sz = (x->sz < y->sz) ? x->sz : y->sz;

357358
358359

/* Add overlapping limbs from both operands */

359360

/* 4x unrolled loop for better performance */

360-

for (i = 0; i + 4 <= x->sz; i += 4) {

361+

for (i = 0; i + 4 <= min_sz; i += 4) {

361362

c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];

362363

z->p[i] = LOW(c);

363364

c >>= DIG_SIZE;

@@ -375,13 +376,20 @@ uadd(mpz_t *z, mpz_t *x, mpz_t *y)

375376

c >>= DIG_SIZE;

376377

}

377378
378-

/* Handle remaining elements */

379-

for (; i < x->sz; i++) {

379+

/* Handle remaining elements in overlap */

380+

for (; i < min_sz; i++) {

380381

c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];

381382

z->p[i] = LOW(c);

382383

c >>= DIG_SIZE;

383384

}

384385
386+

/* Add remaining limbs from x if it's larger */

387+

for (; i < x->sz; i++) {

388+

c += x->p[i];

389+

z->p[i] = LOW(c);

390+

c >>= DIG_SIZE;

391+

}

392+
385393

/* Add remaining limbs from larger operand */

386394

/* 4x unrolled loop for better performance */

387395

for (; i + 4 <= y->sz; i += 4) {

Read the original on github.com ↗