all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* converting numbers to strings in arbitrary base (up to 36)
@ 2011-03-15 18:42 Mirko
  2011-03-15 19:15 ` Pascal J. Bourguignon
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Mirko @ 2011-03-15 18:42 UTC (permalink / raw
  To: help-gnu-emacs

Hi,

This is an elisp question:

I can specify integers in base 2-36 using #xyr..., and I can read them from a file.

But is there a way to write an integer in arbitrary base (again, 2-36) to a file?

I looked at string-to-number, format, and calc

In greater detail,

I have a file where I want to keep a counter (in base 36).
When needed, I want to open the file, read the number.
Occasionally, I want to increment the number, and write it back out.

I can handle reading and writing :-).  It is writing the base 36 that
I don't know how to handle.

Thank you,

Mirko


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: converting numbers to strings in arbitrary base (up to 36)
  2011-03-15 18:42 converting numbers to strings in arbitrary base (up to 36) Mirko
@ 2011-03-15 19:15 ` Pascal J. Bourguignon
  2011-03-15 20:57   ` Mirko
  2011-03-15 19:39 ` Stefan Monnier
  2011-03-15 20:47 ` Johan Bockgård
  2 siblings, 1 reply; 5+ messages in thread
From: Pascal J. Bourguignon @ 2011-03-15 19:15 UTC (permalink / raw
  To: help-gnu-emacs

Mirko <mvukovic@nycap.rr.com> writes:

> This is an elisp question:
>
> I can specify integers in base 2-36 using #xyr..., and I can read them from a file.
>
> But is there a way to write an integer in arbitrary base (again, 2-36) to a file?
>
> I looked at string-to-number, format, and calc
>
> In greater detail,
>
> I have a file where I want to keep a counter (in base 36).
> When needed, I want to open the file, read the number.
> Occasionally, I want to increment the number, and write it back out.
>
> I can handle reading and writing :-).  It is writing the base 36 that
> I don't know how to handle.


For bases eight, ten, and sixteen, you can use format:

    (format "#8r%o #10r%d #16r%x" 42 42 42)
    --> "#8r52 #10r42 #16r2a"



For the other bases, you must implement it yourself, or use
integer-to-base (from 
http://git.informatimago.com/viewgit/index.php?a=viewblob&p=public/emacs&h=94650b080e8a38e9620687b9abd3fcb3e24c6561&hb=e57067965e5def38d5fa18dab0aa75cff3d049b9&f=pjb-utilities.el
)


(loop for b from 2 to 36
      collect (format  "#%dr%s" b (integer-to-base 42 b)))


--> ("#2r101010" "#3r1120" "#4r222" "#5r132" "#6r110" "#7r60" "#8r52"
     "#9r46" "#10r42" "#11r39" "#12r36" "#13r33" "#14r30" "#15r2C"
     "#16r2A" "#17r28" "#18r26" "#19r24" "#20r22" "#21r20" "#22r1K"
     "#23r1J" "#24r1I" "#25r1H" "#26r1G" "#27r1F" "#28r1E" "#29r1D"
     "#30r1C" "#31r1B" "#32r1A" "#33r19" "#34r18" "#35r17" "#36r16")




(defun integer-to-base (decimal base &optional width padchar
                                commachar comma-interval)
  "
DO:      Convert  a decimal  value into  a string  contening the 
         same value expressed into the given base. 1<base<37.
         The optional WIDTH specifies the minimum length of the returned 
         string (0-left-filled), not counting a '-' sign.
SEE-ALSO:float-to-base."
    ;;TODO: Implement commachar, comma-interval
  (cond
   ((not (integerp base))         (error "Invalid base (%S)." base))
   ((or (< base 2) (< 36 base))   (error "Invalid base (%d)." base))
   ((not (integerp decimal))      
    (error "For now, I only convert integer values.")))
  (let ((digits "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
        (buffer (make-string 32 ?0))
        (b 31)
        (sign "")
        )
    (if (< decimal 0)
        (setq sign "-"
              decimal (abs decimal)))
    (while (< 0 decimal)
      (let ((digit   (% decimal base)))
        (aset buffer b (aref digits digit))
        (setq decimal (/ (- decimal digit) base)
              b       (- b 1))))
    (if width (if (< 32 width)
                  (setq sign (concat sign (make-string (- width 32) padchar))
                        width 32)))
    (concat sign 
            (if (and width (< (- 32 width) (+ 1 b) ))
                (substring buffer (- 32 width))
              (if (= b 31) "0" (substring buffer (+ 1 b)))))))






-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: converting numbers to strings in arbitrary base (up to 36)
  2011-03-15 18:42 converting numbers to strings in arbitrary base (up to 36) Mirko
  2011-03-15 19:15 ` Pascal J. Bourguignon
@ 2011-03-15 19:39 ` Stefan Monnier
  2011-03-15 20:47 ` Johan Bockgård
  2 siblings, 0 replies; 5+ messages in thread
From: Stefan Monnier @ 2011-03-15 19:39 UTC (permalink / raw
  To: help-gnu-emacs

> I have a file where I want to keep a counter (in base 36).

string-to-number takes a `base' argument, but that only works one way
(when reading) and the base can only be up to 16, bot up to 36.
So I think you'll have to do the conversion by hand (with the kind of
code you'd typically see in introductory programming books).


        Stefan


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: converting numbers to strings in arbitrary base (up to 36)
  2011-03-15 18:42 converting numbers to strings in arbitrary base (up to 36) Mirko
  2011-03-15 19:15 ` Pascal J. Bourguignon
  2011-03-15 19:39 ` Stefan Monnier
@ 2011-03-15 20:47 ` Johan Bockgård
  2 siblings, 0 replies; 5+ messages in thread
From: Johan Bockgård @ 2011-03-15 20:47 UTC (permalink / raw
  To: help-gnu-emacs

Mirko <mvukovic@nycap.rr.com> writes:

> But is there a way to write an integer in arbitrary base (again, 2-36)
> to a file?
>
> I looked at string-to-number, format, and calc

  (require 'calc-bin)
  (let ((calc-number-radix 36))
    (math-format-radix 71))

    => "1Z"


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: converting numbers to strings in arbitrary base (up to 36)
  2011-03-15 19:15 ` Pascal J. Bourguignon
@ 2011-03-15 20:57   ` Mirko
  0 siblings, 0 replies; 5+ messages in thread
From: Mirko @ 2011-03-15 20:57 UTC (permalink / raw
  To: help-gnu-emacs

On Tuesday, March 15, 2011 3:15:23 PM UTC-4, Pascal J. Bourguignon wrote:
> Mirko <mvuk...@nycap.rr.com> writes:
> 
> > This is an elisp question:
> >
> > I can specify integers in base 2-36 using #xyr..., and I can read them from a file.
> >
> > But is there a way to write an integer in arbitrary base (again, 2-36) to a file?
> >
> > I looked at string-to-number, format, and calc
> >
> > In greater detail,
> >
> > I have a file where I want to keep a counter (in base 36).
> > When needed, I want to open the file, read the number.
> > Occasionally, I want to increment the number, and write it back out.
> >
> > I can handle reading and writing :-).  It is writing the base 36 that
> > I don't know how to handle.
> 
> 
> For bases eight, ten, and sixteen, you can use format:
> 
>     (format "#8r%o #10r%d #16r%x" 42 42 42)
>     --> "#8r52 #10r42 #16r2a"
> 
> 
> 
> For the other bases, you must implement it yourself, or use
> integer-to-base (from 
> http://git.informatimago.com/viewgit/index.php?a=viewblob&p=public/emacs&h=94650b080e8a38e9620687b9abd3fcb3e24c6561&hb=e57067965e5def38d5fa18dab0aa75cff3d049b9&f=pjb-utilities.el
> )
> 
> 
> (loop for b from 2 to 36
>       collect (format  "#%dr%s" b (integer-to-base 42 b)))
> 
> 
> --> ("#2r101010" "#3r1120" "#4r222" "#5r132" "#6r110" "#7r60" "#8r52"
>      "#9r46" "#10r42" "#11r39" "#12r36" "#13r33" "#14r30" "#15r2C"
>      "#16r2A" "#17r28" "#18r26" "#19r24" "#20r22" "#21r20" "#22r1K"
>      "#23r1J" "#24r1I" "#25r1H" "#26r1G" "#27r1F" "#28r1E" "#29r1D"
>      "#30r1C" "#31r1B" "#32r1A" "#33r19" "#34r18" "#35r17" "#36r16")
> 
> 
> 
> 
> (defun integer-to-base (decimal base &optional width padchar
>                                 commachar comma-interval)
>   "
> DO:      Convert  a decimal  value into  a string  contening the 
>          same value expressed into the given base. 1<base<37.
>          The optional WIDTH specifies the minimum length of the returned 
>          string (0-left-filled), not counting a '-' sign.
> SEE-ALSO:float-to-base."
>     ;;TODO: Implement commachar, comma-interval
>   (cond
>    ((not (integerp base))         (error "Invalid base (%S)." base))
>    ((or (< base 2) (< 36 base))   (error "Invalid base (%d)." base))
>    ((not (integerp decimal))      
>     (error "For now, I only convert integer values.")))
>   (let ((digits "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
>         (buffer (make-string 32 ?0))
>         (b 31)
>         (sign "")
>         )
>     (if (< decimal 0)
>         (setq sign "-"
>               decimal (abs decimal)))
>     (while (< 0 decimal)
>       (let ((digit   (% decimal base)))
>         (aset buffer b (aref digits digit))
>         (setq decimal (/ (- decimal digit) base)
>               b       (- b 1))))
>     (if width (if (< 32 width)
>                   (setq sign (concat sign (make-string (- width 32) padchar))
>                         width 32)))
>     (concat sign 
>             (if (and width (< (- 32 width) (+ 1 b) ))
>                 (substring buffer (- 32 width))
>               (if (= b 31) "0" (substring buffer (+ 1 b)))))))
> 
> 
> 
> 
> 
> 
> -- 
> __Pascal Bourguignon__                     http://www.informatimago.com/
> A bad day in () is better than a good day in {}.

Thanks to everyone

Mirko



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-03-15 20:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-15 18:42 converting numbers to strings in arbitrary base (up to 36) Mirko
2011-03-15 19:15 ` Pascal J. Bourguignon
2011-03-15 20:57   ` Mirko
2011-03-15 19:39 ` Stefan Monnier
2011-03-15 20:47 ` Johan Bockgård

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.