GitHub

@@ -2545,13 +2545,20 @@ dc_scratch_clear(mpz_ctx_t *ctx, dc_to_s_scratch_t *scratch)

25452545

* The caller must ensure num_digits >= actual digits in x.

25462546

* Leading zeros are added if x has fewer digits than num_digits.

25472547

*/

2548-

/* Batch divisor: 10^9 for extracting 9 digits at once */

2548+

/* Batch divisor for extracting multiple digits at once */

2549+

#ifdef MRB_NO_MPZ64BIT

2550+

/* 16-bit limbs: 10^4 fits in 16 bits */

2551+

#define BATCH_DIVISOR 10000UL

2552+

#define BATCH_DIGITS 4

2553+

#else

2554+

/* 32-bit limbs: 10^9 fits in 32 bits */

25492555

#define BATCH_DIVISOR 1000000000UL

25502556

#define BATCH_DIGITS 9

2557+

#endif

2551255825522559

/*

2553-

* Divide limb array by 10^9 in place, returning remainder.

2554-

* Used for extracting 9 decimal digits at a time.

2560+

* Divide limb array by BATCH_DIVISOR in place, returning remainder.

2561+

* Used for extracting BATCH_DIGITS decimal digits at a time.

25552562

* Compilers optimize constant division to multiplication+shift.

25562563

*/

25572564

static mp_limb

@@ -2598,18 +2605,20 @@ mpz_get_str_dc_recur(mpz_ctx_t *ctx, char *s, mpz_t *x, size_t num_digits,

25982605

mpz_set(ctx, tmp, x);

2599260626002607

while (pos > 0 && !zero_p(tmp)) {

2601-

/* Divide by 10^9 in place, get remainder as 9 digits */

2608+

/* Divide by BATCH_DIVISOR in place, get remainder as BATCH_DIGITS digits */

26022609

mp_limb batch = mpn_div_batch(tmp->p, tmp->sz);

26032610

trim(tmp);

260426112605-

/* Convert remainder (0-999999999) to 9 digits using table lookup */

2606-

/* Extract last digit (9th) separately since 9 is odd */

2612+

/* Convert remainder to BATCH_DIGITS digits using table lookup */

2613+

#if (BATCH_DIGITS % 2) == 1

2614+

/* Extract last digit separately since BATCH_DIGITS is odd */

26072615

if (pos > 0) {

26082616

s[--pos] = '0' + (char)(batch % 10);

26092617

batch /= 10;

26102618

}

2611-

/* Extract remaining 8 digits as 4 pairs using lookup table */

2612-

for (int d = 0; d < 4 && pos >= 2; d++) {

2619+

#endif

2620+

/* Extract remaining digits as pairs using lookup table */

2621+

for (int d = 0; d < BATCH_DIGITS / 2 && pos >= 2; d++) {

26132622

mp_limb pair = batch % 100;

26142623

batch /= 100;

26152624

s[--pos] = digit_pairs[pair * 2 + 1];

Read the original on github.com ↗