Author |
Message |
Ernest Smi #1 / 17
|
 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 |
|
 |
Kent M Pitma #2 / 17
|
 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 |
|
 |
Dorai Sitar #3 / 17
|
 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 |
|
 |
Marco Antoniott #4 / 17
|
 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 |
|
 |
Ralf Muschal #5 / 17
|
 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 |
|
 |
Dorai Sitar #6 / 17
|
 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 |
|
 |
Barry Margoli #7 / 17
|
 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 |
|
 |
Kent M Pitma #8 / 17
|
 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 |
|
 |
Kent M Pitma #9 / 17
|
 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 |
|
 |
Dorai Sitar #10 / 17
|
 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 |
|
 |
Marco Antoniott #11 / 17
|
 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 |
|
 |
Patrick A. O'Donne #12 / 17
|
 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 |
|
 |
Dorai Sitar #13 / 17
|
 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 |
|
 |
Kent M Pitma #14 / 17
|
 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 |
|
 |
Barry Margoli #15 / 17
|
 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 |
|
|