~ chicken-core (master) 4c556509502d41b539bc957bba58d3174b84c799


commit 4c556509502d41b539bc957bba58d3174b84c799
Author:     Diego A. Mundo <dieggsy@pm.me>
AuthorDate: Thu Jan 15 01:21:05 2026 -0500
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Fri Jan 16 15:18:05 2026 +0100

    Make number->string work with bases up to 36
    
    Signed-off-by: Peter Bex <peter@more-magic.net>

diff --git a/NEWS b/NEWS
index 698fe2d2..adb64e62 100644
--- a/NEWS
+++ b/NEWS
@@ -84,6 +84,8 @@
   - Added the (chicken version) module.
   - "delete-file*" and "delete-file" now behave consistently with
     broken symlinks.
+  - number->string now accepts bases up to 36, where before it only accepted
+    bases up to 16 (thanks to Diego A. Mundo)
 
 - Syntax expander:
   - `syntax-rules' attempts to better support tail patterns with ellipses
diff --git a/manual/Module (scheme base) b/manual/Module (scheme base)
index 7dae7d87..3d3cd302 100644
--- a/manual/Module (scheme base)	
+++ b/manual/Module (scheme base)	
@@ -2535,11 +2535,11 @@ reported.
 
 Radix must be an exact integer.  The R7RS standard only requires
 implementations to support 2, 8, 10, or 16, but CHICKEN allows any
-radix between 2 and 36, inclusive (note: a bug in CHICKEN 5 currently
-limits the upper bound to 16).  If omitted, radix defaults to
-10. The procedure number->string takes a number and a radix and
-returns as a string an external representation of the given number in
-the given radix such that
+radix between 2 and 36, inclusive (note: due to a bug, flonums with
+fractional components always use radix 10, irrespective of the argument).
+If omitted, radix defaults to 10. The procedure number->string takes
+a number and a radix and returns as a string an external
+representation of the given number in the given radix such that
 
  (let ((number number)
        (radix radix))
diff --git a/runtime.c b/runtime.c
index 084c7a4f..7f038935 100644
--- a/runtime.c
+++ b/runtime.c
@@ -11135,7 +11135,7 @@ static C_regparm double decode_flonum_literal(C_char *str)
 
 static char *to_n_nary(C_uword num, C_uword base, int negp, int as_flonum)
 {
-  static char *digits = "0123456789abcdef";
+  static char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
   char *p;
   C_uword shift = C_ilen(base) - 1;
   int mask = (1 << shift) - 1;
@@ -11203,7 +11203,7 @@ void C_ccall C_fixnum_to_string(C_word c, C_word *av)
     radix = ((c == 3) ? 10 : C_unfix(av[ 3 ])),
     neg = ((num & C_INT_SIGN_BIT) ? 1 : 0);
 
-  if (radix < 2 || radix > 16) {
+  if (radix < 2 || radix > 36) {
     barf(C_BAD_ARGUMENT_TYPE_BAD_BASE_ERROR, "number->string", C_fix(radix));
   }
 
@@ -11287,7 +11287,7 @@ void C_ccall C_integer_to_string(C_word c, C_word *av)
     int len, radix_shift;
     size_t nbits;
 
-    if ((radix < 2) || (radix > 16)) {
+    if ((radix < 2) || (radix > 36)) {
       barf(C_BAD_ARGUMENT_TYPE_BAD_BASE_ERROR, "number->string", C_fix(radix));
     }
 
@@ -11327,7 +11327,7 @@ void C_ccall C_integer_to_string(C_word c, C_word *av)
 
 static void bignum_to_str_2(C_word c, C_word *av)
 {
-  static char *characters = "0123456789abcdef";
+  static char *characters = "0123456789abcdefghijklmnopqrstuvwxyz";
   C_word
     self = av[ 0 ],
     string = av[ 1 ],
Trap