unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: Bengt Richter <bokr@bokr.com>
To: tomas@tuxteam.de
Cc: 42012@debbugs.gnu.org
Subject: bug#42012: Reference Manual and Docstring on number->string
Date: Wed, 24 Jun 2020 05:49:58 +0200	[thread overview]
Message-ID: <20200624034958.GA2949@LionPure> (raw)
In-Reply-To: <20200623083412.GA3290@tuxteam.de>

On +2020-06-23 10:34:12 +0200, tomas@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     \x7f=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





      reply	other threads:[~2020-06-24  3:49 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-22 22:51 bug#42012: Reference Manual and Docstring on number->string Sebastian Miele
2020-06-23  8:34 ` tomas
2020-06-24  3:49   ` Bengt Richter [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200624034958.GA2949@LionPure \
    --to=bokr@bokr.com \
    --cc=42012@debbugs.gnu.org \
    --cc=tomas@tuxteam.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).