@@ -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 */
25572564static mp_limb
@@ -2598,18 +2605,20 @@ mpz_get_str_dc_recur(mpz_ctx_t *ctx, char *s, mpz_t *x, size_t num_digits,
25982605mpz_set(ctx, tmp, x);
2599260626002607while (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 */
26022609mp_limb batch = mpn_div_batch(tmp->p, tmp->sz);
26032610trim(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 */
26072615if (pos > 0) {
26082616s[--pos] = '0' + (char)(batch % 10);
26092617batch /= 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++) {
26132622mp_limb pair = batch % 100;
26142623batch /= 100;
26152624s[--pos] = digit_pairs[pair * 2 + 1];