From ... From: Erik Naggum Subject: Re: String to real Date: 2000/06/08 Message-ID: <3169487578816052@naggum.no>#1/1 X-Deja-AN: 632776321 Content-Transfer-Encoding: 8bit References: <393FDD06.ED9BCA0C@nexo.es> mail-copies-to: never Content-Type: text/plain; charset=iso-8859-1 X-Complaints-To: newsmaster@eunet.no X-Trace: oslo-nntp.eunet.no 960499870 20227 195.0.192.66 (8 Jun 2000 21:31:10 GMT) Organization: Naggum Software; vox: +47 8800 8879; fax: +47 8800 8601; http://www.naggum.no User-Agent: Gnus/5.0803 (Gnus v5.8.3) Emacs/20.6 Mime-Version: 1.0 NNTP-Posting-Date: 8 Jun 2000 21:31:10 GMT Newsgroups: comp.lang.lisp * Tim Bradshaw | This comes up quite regularly. There really isn't a good answer -- | there is PARSE-INTEGER but not PARSE-FLOAT. People will tell you to | use READ-FROM-STRING, but this is generally bad advice because you | have no idea what's in the string, and so you could get back | anything, or perform arbitrarily complex computations unless you | turn off *READ-EVAL*. So be careful if you do this. This is fairly strange advice. Let's decide to _write_ parse-float, instead of this repeated lamentation. Somewhere in every Common Lisp implementation, there's a function that takes a strings of characters and returns a floating point number. It may be hard to call, it may require other internals to be set up properly, or it may be embedded in something else that makes it hard to access right away, but it's there. Language design is all about deciding on interfaces to well-defined functionality, _not_ about implementing them nicely. In fact, we're allowed to be as implementation-dependent as we could possibly get if we adhere to the principle of exporting and advertising a clean interface. Before you object, consider that it is a lot cleaner than asking people to go off and do all the implementation-dependent stuff in their _own_ code, because that's just plain gross. For instance, in Allegro CL, there's a nice little function called make-float that returns a floating point number if given a read-buffer with characters satisfying the pattern matching a floating point number in it, but a read-buffer is an _entrenched_ data type, and accessing it is non-trivial without sources, so only supported customers who have signed the limited source license can use it. I'm not super-thrilled about this, but here's how to use it, given an input string with its usual start and end positions: #+franz-inc (defun parse-float (string &key (start 0) end) (let* ((length (- (or end (length string)) start))) (excl::make-float (vector (subseq string start end) length 0 length)))) This function will parse a floating point number and return it just as the reader would (like obeying *read-default-float-format*), but will return 0.0 if there is no discernible floating point number in the string you gave it. Caveat emptor or something. An improvement on this function is to take a string and figure out where the floating point number ends and return that position, too. _Or_ you could just write some FFI wrappping around the math library functions of your favorite operating system's "native" compiler, but that's completely immaterial to me: All I want is a function called "parse-float" which takes a string containing the usual read syntax for floating point numbers and gives me the floating point number that would print back as that string, if at all possible, or the nearest floating point model number¹ if not. #:Erik ------- ¹ That's what they call it in Ada, anyway. -- If this is not what you expected, please alter your expectations.