GNU bug report logs - #42012
Reference Manual and Docstring on number->string

Previous Next

Package: guile;

Reported by: sebastian.miele <at> gmail.com

Date: Mon, 22 Jun 2020 22:52:01 UTC

Severity: normal

To reply to this bug, email your comments to 42012 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guile <at> gnu.org:
bug#42012; Package guile. (Mon, 22 Jun 2020 22:52:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to sebastian.miele <at> gmail.com:
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Mon, 22 Jun 2020 22:52:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Sebastian Miele <sebastian.miele <at> gmail.com>
To: bug-guile <at> gnu.org
Subject: Reference Manual and Docstring on number->string
Date: Tue, 23 Jun 2020 00:51:23 +0200
Guile 3.0.3. The reference manual and the docstring of number->string
say: "If N is inexact, a radix of 10 will be used." But that is not what
happens, e.g.,

  (let ((x 4.0)) (and (inexact? x) (number->string x 3)))

evaluates to "11.0" instead of #f or "4.0". Probably "if RADIX is not
supplied, a radix of 10 will be used" is meant.




Information forwarded to bug-guile <at> gnu.org:
bug#42012; Package guile. (Tue, 23 Jun 2020 08:35:02 GMT) Full text and rfc822 format available.

Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):

From: <tomas <at> tuxteam.de>
To: bug-guile <at> gnu.org
Subject: Re: bug#42012: Reference Manual and Docstring on number->string
Date: Tue, 23 Jun 2020 10:34:12 +0200
[Message part 1 (text/plain, inline)]
On Tue, Jun 23, 2020 at 12:51:23AM +0200, Sebastian Miele wrote:
> Guile 3.0.3. The reference manual and the docstring of number->string
> say: "If N is inexact, a radix of 10 will be used." But that is not what
> happens, e.g.,
> 
>   (let ((x 4.0)) (and (inexact? x) (number->string x 3)))
> 
> evaluates to "11.0" instead of #f or "4.0". Probably "if RADIX is not
> supplied, a radix of 10 will be used" is meant.

Confirmed for 3.0.2. At first I thought that the fractional part being
zero could be significant (as in your example), but

  scheme@(guile-user)> (number->string 0.3333333333333333 3)
  $5 = "0.1"

is clearly being done in radix 3, fractional part and all.

Cheers
-- t
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-guile <at> gnu.org:
bug#42012; Package guile. (Wed, 24 Jun 2020 03:51:01 GMT) Full text and rfc822 format available.

Message #11 received at 42012 <at> debbugs.gnu.org (full text, mbox):

From: Bengt Richter <bokr <at> bokr.com>
To: tomas <at> tuxteam.de
Cc: 42012 <at> debbugs.gnu.org
Subject: Re: bug#42012: Reference Manual and Docstring on number->string
Date: Wed, 24 Jun 2020 05:49:58 +0200
On +2020-06-23 10:34:12 +0200, tomas <at> tuxteam.de wrote:
> On Tue, Jun 23, 2020 at 12:51:23AM +0200, Sebastian Miele wrote:
> > Guile 3.0.3. The reference manual and the docstring of number->string
> > say: "If N is inexact, a radix of 10 will be used." But that is not what
> > happens, e.g.,
> > 
> >   (let ((x 4.0)) (and (inexact? x) (number->string x 3)))
> > 
> > evaluates to "11.0" instead of #f or "4.0". Probably "if RADIX is not
> > supplied, a radix of 10 will be used" is meant.
> 
> Confirmed for 3.0.2. At first I thought that the fractional part being
> zero could be significant (as in your example), but
> 
>   scheme@(guile-user)> (number->string 0.3333333333333333 3)
>   $5 = "0.1"
> 
> is clearly being done in radix 3, fractional part and all.
> 
> Cheers
> -- t

There are some other things that might be mentioned also,
like the characters used by number->string and more surprisingly by string->number :-)

You can try copying the following into ./show-string2num-chars.scm somewhere and chmod 755 it
and try running it, but it will produce one item per line, so it will be handy to let pr format that, like
 ./show-string2num-chars.scm|pr -t -8|uniq|sed -e 's:^:;;;; :'
 Unless your system is different, you should get the table in the comments below.

Since string->number will accept characters past #\z there may be a bug?
See some experiments and speculations below the "BTW" ;-)

--8<---------------cut here---------------start------------->8---
#!/usr/bin/env -S guile --no-auto-compile -e main -s
!#
;;;; show-string2num-chars.scm
(define (main args)
  (begin
    (let*((chrs255 (cdr (map integer->char (iota 256))))
	  (ints255 (map (lambda (c) (string->number (string c) 256)) chrs255))
	  (c2iprs  (map (lambda (c i) (cons c i)) chrs255 ints255))
	  (okprs (filter (lambda (pr) (cdr pr)) c2iprs))
	  ;;
	  )
      (begin
	(map (lambda (pr) (format #t "~a=~a\n" (car pr) (cdr pr))) okprs)
	;;
	))
    ;;
    ))

;;;; running this from emacs right after the following line showing the emacs command:
;;;; Esc 1 Esc ! ./show-string2num-chars.scm|pr -t -8|uniq|sed -e 's:^:;;;; :'
;;;; 0=0	 9=9	  I=18	   R=27	    Z=35     h=17     p=25     x=33
;;;; 1=1	 A=10	  J=19	   S=28	    a=10     i=18     q=26     y=34
;;;; 2=2	 B=11	  K=20	   T=29	    b=11     j=19     r=27     z=35
;;;; 3=3	 C=12	  L=21	   U=30	    c=12     k=20     s=28     {=36
;;;; 4=4	 D=13	  M=22	   V=31	    d=13     l=21     t=29     |=37
;;;; 5=5	 E=14	  N=23	   W=32	    e=14     m=22     u=30     }=38
;;;; 6=6	 F=15	  O=24	   X=33	    f=15     n=23     v=31     ~=39
;;;; 7=7	 G=16	  P=25	   Y=34	    g=16     o=24     w=32     =40
;;;; 8=8	 H=17	  Q=26

;;;; #\z=35 #\{=36 #\|=37 #\}=38 #\delete=#f 
;;;; scheme@(guile-user) [6]> 

;;;; BTW

;;;; scheme@(guile-user) [6]> (string-for-each (lambda (c) (format #t "~s=~a " c (string->number (string c) 40))) "z{|}\x7f")(newline)
;;;;
;;;; #\z=35 #\{=36 #\|=37 #\}=38 #\delete=#f
;;;; scheme@(guile-user) [6]>  

;;;; it will also apparently happily accept multiple characters z through \x7f and convert them with any radix exceeding
;;;; the largest "digit value
;;;; scheme@(guile-user) [8]> (for-each (lambda (s) (format #t "~s=~a " s (string->number s 1000))) '("0" "1" "10" "z{" "|}" "\x7f")) (newline)
;;;; "0"=0 "1"=1 "10"=1000 "z{"=35036 "|}"=37038 "\x7f"=40 
;;;; scheme@(guile-user) [8]> 

;;;; the following makes me think possibly the unicode value is taken and masked with 0x7f for ascii and then
;;;; accepted if >= 97 (#\a) (accidentally including > 122 (#\z), only checking for [0-9] and [A-Z] if maked value is less than 97 (#\a)
;;;;scheme@(guile-user) [8]> (for-each (lambda (s) (format #t "~s=~a " s (string->number s 1000))) '("0" "1" "10" "111" "z{" "|}" "\x7f\x80" "\x80\x7f" "\u807e")) (newline)
;;;; "0"=0 "1"=1 "10"=1000 "111"=1001001 "z{"=35036 "|}"=37038 "\x7f\x80"=40041 "\x80\x7f"=#f "聾"=39 

;;;; I'll leave it to others to explore further :)

;;;; Note, though, that the inverse -- number->string -- will not accept a radix outide of 2-36:
;;;; scheme@(guile-user) [10]> (number->string (+ (* 34 36) 35) 36)
;;;; $18 = "yz"
;;;; scheme@(guile-user) [10]> (number->string (+ (* 34 36) 35) 40)
;;;; ERROR: In procedure number->string:
;;;; Value out of range 2 to 36: 40
;;;; 
;;;; Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
;;;; scheme@(guile-user) [11]> (number->string (+ (* 34 36) 35) 37)
;;;; ERROR: In procedure number->string:
;;;; Value out of range 2 to 36: 37
;;;; 
--8<---------------cut here---------------end--------------->8---

-- 
Regards,
Bengt Richter




This bug report was last modified 4 years and 188 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.