Common Lisp: String to Number conversion 
Author Message
 Common Lisp: String to Number conversion

Hello,

Does anyone have code for converting a string to number? Note that I do
not use elisp, but common Lisp.

Thanks in advance,

Greetings,

Ernest

(BTW: Can you please send it directly to me by email?)



Fri, 26 Sep 2003 15:35:39 GMT  
 Common Lisp: String to Number conversion

Quote:

> Does anyone have code for converting a string to number? Note that I do
> not use elisp, but common Lisp.

What kind of number?

Common Lisp's PARSE-INTEGER will convert a string to an integer.
See CLHS for details.

For portable float-parsing, Common Lisp's READ-FROM-STRING will
perform the action of READ on a string.  It is recommended that you
bind *READ-EVAL* to NIL to avoid trojan horses if you use this.
There is also a float-parsing library floating around, somewhere;
see either the ALU web site or the CMU AI repository.

http://www.alu.org/  is a good place to start looking for
things generally, including the FAQ.



Fri, 26 Sep 2003 16:11:20 GMT  
 Common Lisp: String to Number conversion

Quote:
>Hello,

>Does anyone have code for converting a string to number? Note that I do
>not use elisp, but common Lisp.

If what you want is something like the Scheme
string->number, then the following Common-Lisp
definition should be serviceable.

(defun string-to-number (s &optional (b 10))
  (let ((*read-base* b))
    (let ((n (read-from-string s nil)))
      (if (numberp n) n nil))))

--d



Wed, 01 Oct 2003 01:23:58 GMT  
 Common Lisp: String to Number conversion

Quote:


> >Hello,

> >Does anyone have code for converting a string to number? Note that I do
> >not use elisp, but common Lisp.

> If what you want is something like the Scheme
> string->number, then the following Common-Lisp
> definition should be serviceable.

> (defun string-to-number (s &optional (b 10))
>   (let ((*read-base* b))
>     (let ((n (read-from-string s nil)))
>       (if (numberp n) n nil))))

Slightly better (IHMO)

==============================================================================
* (defun string-to-number (s &optional (b 10))
    (let* ((*read-base* b)
           (n (read-from-string s nil))
          )
      (if (numberp n)
          n
          (error "String ~S does not contain a NUMBER." s))))
STRING-TO-NUMBER
* (string-to-number "#C(1 101)" 2)
#C(1 5)
* (string-to-number "10/A" 16)
8/5
* (string-to-number "10/A")
Invoking de{*filter*}...
==============================================================================

Of course, complex numbers and rationals are available in CL, but not
as readily in other languages. :)

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://www.*-*-*.com/
               "Hello New York! We'll do what we can!"
                        Bill Murray in `Ghostbusters'.



Wed, 01 Oct 2003 02:13:44 GMT  
 Common Lisp: String to Number conversion

Quote:
> perform the action of READ on a string.  It is recommended that you
> bind *READ-EVAL* to NIL to avoid trojan horses if you use this.

How widespread are such attack?

IIRC xlispstat has no *READ-EVAL* at all and evaluates "#."-stuff
always, but I've never heard about such things (which should be even
more probable with xlispstat which is intended to be run by lusers).

Ralf

--
GS d->? s:++>+++ a C++++ UL+++ UH++ P++ L++ E+++ W- N++ o-- K- w--- !O M- V-
PS+>++ PE Y+>++ PGP+ !t !5 !X !R !tv  b+++ DI+++ D?  G+ e++++ h+ r? y?



Wed, 01 Oct 2003 00:21:40 GMT  
 Common Lisp: String to Number conversion


Quote:


>> (defun string-to-number (s &optional (b 10))
>>   (let ((*read-base* b))
>>     (let ((n (read-from-string s nil)))
>>       (if (numberp n) n nil))))

>Slightly better (IHMO)

>==============================================================================
>* (defun string-to-number (s &optional (b 10))
>    (let* ((*read-base* b)
>       (n (read-from-string s nil))
>      )
>      (if (numberp n)
>      n
>      (error "String ~S does not contain a NUMBER." s))))
>STRING-TO-NUMBER
>* (string-to-number "#C(1 101)" 2)
>#C(1 5)
>* (string-to-number "10/A" 16)
>8/5
>* (string-to-number "10/A")
>Invoking de{*filter*}...
>==============================================================================

This is a less useful procedure.  A number-or-nil
string-to-number allows one to check if a string
represents a number, and then perform one of two
actions based on that check.  

A more useful improvement would be one that ensures
that string-to-number returns nil for strings
like "1600 Pennsylvanie Ave".  

--d



Wed, 01 Oct 2003 03:55:45 GMT  
 Common Lisp: String to Number conversion

Quote:




>>> (defun string-to-number (s &optional (b 10))
>>>   (let ((*read-base* b))
>>>     (let ((n (read-from-string s nil)))
>>>       (if (numberp n) n nil))))

>>Slightly better (IHMO)

>>==============================================================================
>>* (defun string-to-number (s &optional (b 10))
>>    (let* ((*read-base* b)
>>           (n (read-from-string s nil))
>>          )
>>      (if (numberp n)
>>          n
>>          (error "String ~S does not contain a NUMBER." s))))
>>STRING-TO-NUMBER
>>* (string-to-number "#C(1 101)" 2)
>>#C(1 5)
>>* (string-to-number "10/A" 16)
>>8/5
>>* (string-to-number "10/A")
>>Invoking de{*filter*}...
>>==============================================================================

>This is a less useful procedure.  A number-or-nil
>string-to-number allows one to check if a string
>represents a number, and then perform one of two
>actions based on that check.  

And why can't you do that with the second version, by using an error
handler?

Quote:
>A more useful improvement would be one that ensures
>that string-to-number returns nil for strings
>like "1600 Pennsylvanie Ave".  

True.  READ-FROM-STRING returns a second value, the number of characters
that were consumed.  If this is not equal to the length of the string, then
you know that there was extraneous text in the string:

(defun string-to-number (s &optional (*read-base* 10))
  (multiple-value-bind (n count)
      (read-from-string s nil)
    (if (and (numberp n)
             (= count (length s)))
        n
        (error "String ~S is not a NUMBER." s))))

--

Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.



Wed, 01 Oct 2003 04:08:35 GMT  
 Common Lisp: String to Number conversion

Quote:

> True.  READ-FROM-STRING returns a second value, the number of characters
> that were consumed.  If this is not equal to the length of the string, then
> you know that there was extraneous text in the string:

> (defun string-to-number (s &optional (*read-base* 10))
>   (multiple-value-bind (n count)
>       (read-from-string s nil)
>     (if (and (numberp n)
>              (= count (length s)))
>         n
>         (error "String ~S is not a NUMBER." s))))

Actually, to quote CLHS on the secondary value, position:

 position---an integer greater than or equal to zero, and less than
  or equal to one more than the length of the string.

I can't remember why it was allowed to be "one more than", but anyway
a red flag goes up in my brain when people don't do
  (>= pos (length string))

Also, while I'm in there, I want to add a plug for binding *READ-EVAL*
to NIL while doing anything like this that doesn't reuire #. for its
correct function.  No sense inviting trojan horses.



Wed, 01 Oct 2003 04:38:30 GMT  
 Common Lisp: String to Number conversion

Quote:


> > perform the action of READ on a string.  It is recommended that you
> > bind *READ-EVAL* to NIL to avoid trojan horses if you use this.

> How widespread are such attack?

 (1) It has been done.
 (2) There was no good reason for it to succeed.

But I think in general it is a *bad* question to ask, since whether there
is a danger is not a function of past action.

Quote:
> IIRC xlispstat has no *READ-EVAL* at all and evaluates "#."-stuff
> always, but I've never heard about such things (which should be even
> more probable with xlispstat which is intended to be run by lusers).

Depends on whether the data stream is open to outside users.  Certainly,
some uses are safe, if the client is provably a nice guy.  But what's the
point in building vulnerable software when it's so easy to make it solid?


Wed, 01 Oct 2003 04:44:25 GMT  
 Common Lisp: String to Number conversion


Quote:


>>This is a less useful procedure.  A number-or-nil
>>string-to-number allows one to check if a string
>>represents a number, and then perform one of two
>>actions based on that check.  

>And why can't you do that with the second version, by using an error
>handler?

Of course it is possible, but it is a complicated
way of going about the matter.  A valid-or-nil
procedure doubles as an easy-to-use predicate, and that
is a good thing.  

--d



Wed, 01 Oct 2003 22:57:18 GMT  
 Common Lisp: String to Number conversion

Quote:





> >>This is a less useful procedure.  A number-or-nil
> >>string-to-number allows one to check if a string
> >>represents a number, and then perform one of two
> >>actions based on that check.  

> >And why can't you do that with the second version, by using an error
> >handler?

> Of course it is possible, but it is a complicated
> way of going about the matter.  A valid-or-nil
> procedure doubles as an easy-to-use predicate, and that
> is a good thing.  

Good point.  Let's get closer to "The Right Thing"....

(defun string-to-number (s &key
                           ((:read-base *read-base*) *read-base*)
                           (parse-error-p t)
                           eof-error-p
                           eof-value)
  (let ((*read-eval* nil))
    (multiple-value-bind (n count)
        (read-from-string s eof-error-p eof-value)
      (if (and (numberp n) (= count (length s)))
          n
          (when parse-error-p
            (error "String ~S is not a NUMBER." s))))))

Not many ways to achieve the same in Scheme.....

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
               "Hello New York! We'll do what we can!"
                        Bill Murray in `Ghostbusters'.



Thu, 02 Oct 2003 00:38:23 GMT  
 Common Lisp: String to Number conversion

Quote:


> > perform the action of READ on a string.  It is recommended that you
> > bind *READ-EVAL* to NIL to avoid trojan horses if you use this.

> How widespread are such attack?

I don't know how widespread they are, but check out Scientific
American, Dec 2000, p. 20.


Fri, 03 Oct 2003 21:22:58 GMT  
 Common Lisp: String to Number conversion


Quote:

>Good point.  Let's get closer to "The Right Thing"....

>(defun string-to-number (s &key
>                       ((:read-base *read-base*) *read-base*)
>                       (parse-error-p t)
>                       eof-error-p
>                       eof-value)
>  (let ((*read-eval* nil))
>    (multiple-value-bind (n count)
>    (read-from-string s eof-error-p eof-value)
>      (if (and (numberp n) (= count (length s)))
>      n
>      (when parse-error-p
>        (error "String ~S is not a NUMBER." s))))))

>Not many ways to achieve the same in Scheme.....

Actually, I am now persuaded that my valid-or-nil
approach may not be all that useful in Common Lisp.
Without a cond syntax that can exploit them,
valid-or-nil procedures have much less going for
them than I implied.  Eg,

(cond ...                                    ; *wrong*
      ((valid-or-nil-procedure its-args) =>
         #'(lambda (non-nil-result)
             (do-something-with non-nil-result)))
      ...)

(It isn't that this kind of thing isn't possible in CL
too, but built-in syntax and usage are not behind it.)

--d



Fri, 03 Oct 2003 23:20:53 GMT  
 Common Lisp: String to Number conversion

Quote:

> Actually, I am now persuaded that my valid-or-nil
> approach may not be all that useful in Common Lisp.
> Without a cond syntax that can exploit them,
> valid-or-nil procedures have much less going for
> them than I implied.  Eg,

> (cond ...                                    ; *wrong*
>       ((valid-or-nil-procedure its-args) =>
>          #'(lambda (non-nil-result)
>              (do-something-with non-nil-result)))
>       ...)

Not necessarily.  First, the valid-or-nil thing is still quite useful
in the case of (or (parse-float foo) (error "Not a float: ~S" foo)).

Further, both the total text involved in doing the following seems
not materially different than what you have to do in Scheme (and
gets to be a lot less if you get to re-use the temp variable more than
once since you can share the setup.)

  (let (val)
    (cond ((setq val (valid-or-nil-procedure its-args))
           (do-something-with val))
          ...))

Not to mention the fact that CL doesn't exactly keep you from extending
COND to do what you want.  Either you can call it KOND or you can shadow
COND.

In spite of the supposed cuteness of the syntax in Scheme, I never really
got into using it a whole lot.  Fortunately, the need to use it doesn't
seem to me to come up much in either language, since most often there are
other transformations that have to be done, too.

I've had to write the above let only about 5 times in my career, I'd
bet, and yet I write and productively use valid-or-nil kinds of things
all the time. Not much of a stat, I suppose, since it's both personal
and anecdotal.  Even so, it makes me think this is not a large issue.

Btw, I often have these false-or-value things yield two values, NIL
and string failure message, when they fail.  That lets them be used in
even more circumstances, plus is informative in debugging even if it's
never used in code.



Fri, 03 Oct 2003 23:39:43 GMT  
 Common Lisp: String to Number conversion

Quote:

>Of course it is possible, but it is a complicated
>way of going about the matter.  A valid-or-nil
>procedure doubles as an easy-to-use predicate, and that
>is a good thing.  

It's easy to turn a signalling procedure into a valid-or-nil procedure by
wrapping the call in IGNORE-ERRORS.

--

Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.



Fri, 03 Oct 2003 23:54:36 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. What I want from my Common Lisp vendor and the Common Lisp community

2. lucid common lisp -- C -- Common lisp intercallability

3. Lucid (Sun) Common Lisp vs Allegro (Franz) Common Lisp - the Summary

4. Lucid (Sun) Common Lisp vs Allegro (Franz) Common Lisp

5. Sun Common Lisp vs. Allegro Common Lisp

6. Common Lisp The Language beta texinfo conversion

7. Q: String To Number Conversion

8. BUG: Scientific Number to String/String to Number

9. Problem with STRING to NUMBER conversion

10. number to string .... string to number

11. String to number conversion

12. string to number conversion

 

 
Powered by phpBB® Forum Software