mruby-bigint: fix D&C to_s digit loss at split boundary

When converting large numbers to strings using D&C algorithm, the
base case extracts digits in batches of 9 (for 32-bit limbs). The
extraction logic: 1 leading digit + 4 pairs (8 digits) = 9 digits.

The pair extraction loop condition `pos >= 2` exits when pos < 2,
but when the remaining batch still has value and pos == 1, that
final digit was being lost and replaced with '0' by the padding loop.

This caused roundtrip failures (x.to_s.to_i != x) for numbers just
above the D&C threshold (1000 digits), where the split boundary
produced a lo part requiring exactly the right number of digits to
trigger this edge case.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-01-13 08:42:19 +09:00
parent 147b341863
commit 5fd8b44502
+4
View File
@@ -2609,6 +2609,10 @@ mpz_to_s_dc_recur(mpz_ctx_t *ctx, char *s, mpz_t *x, size_t num_digits,
s[--pos] = digit_pairs[pair * 2 + 1];
s[--pos] = digit_pairs[pair * 2];
}
/* Extract any remaining single digit when pos == 1 */
if (pos > 0 && batch > 0) {
s[--pos] = '0' + (char)(batch % 10);
}
/* Swap tmp and q pointers for next iteration */
mpz_t *swap = tmp;