From: Slobodan M. <slo...@gm...> - 2010-11-10 22:09:37
|
Hi. I have tried converting strings to numbers, and I have found the example using read-from-string. Unfortunately, it only accepts numbers formatted using decimal dot. Is there any kind of support for the number format using decimal comma? I have tried searching, but all I could find is the support for the various code pages. If not, is there an library that would provide the support for the various number formats? |
From: <pj...@in...> - 2010-11-11 03:57:04
|
Slobodan Milnović <slo...@gm...> writes: > I have tried converting strings to numbers, and I have found the > example using read-from-string. Unfortunately, it only accepts numbers > formatted using decimal dot. What do you mean? * (mapcar 'read-from-string '("123" "123.456" "1e6" "#36rHelloWorld" "42.")) (123 123.456 1000000.0 1767707668033969 42) * -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}. |
From: Kalyanov D. <kal...@gm...> - 2010-11-11 04:03:16
|
On Wed, 2010-11-10 at 23:09 +0100, Slobodan Milnović wrote: > Hi. > > I have tried converting strings to numbers, and I have found the > example using read-from-string. Unfortunately, it only accepts numbers > formatted using decimal dot. > > Is there any kind of support for the number format using decimal > comma? I have tried searching, but all I could find is the support for > the various code pages. If not, is there an library that would provide > the support for the various number formats? You should try cl-l10n [1]. It has a 'parse-number' function and it supports multiple locales. [1] http://common-lisp.net/project/cl-l10n/ |
From: Teemu L. <tli...@ik...> - 2010-11-11 04:51:46
|
* 2010-11-10 23:09 (+0100), Slobodan Milnović wrote: > I have tried converting strings to numbers, and I have found the > example using read-from-string. Unfortunately, it only accepts numbers > formatted using decimal dot. > > Is there any kind of support for the number format using decimal > comma? I have tried searching, but all I could find is the support for > the various code pages. If not, is there an library that would provide > the support for the various number formats? I have a function which reads a decimal number from string and turns it to an exact number (not a floating point). Decimal separator character can be changed with optional argument. (read-number-from-string "-1,2" #\,) => -6/5 (defun number-string-to-integer (string) (handler-case (parse-integer string) (t () nil))) (defun number-string-to-fractional (string) (loop for i = 1/10 then (/ i 10) for c across string unless (char<= #\0 c #\9) return nil sum (* i (position c "0123456789")))) (defun read-number-from-string (string &optional (decimal-separator #\,)) (setf string (string-trim '(#\Space #\Tab) string)) (when (plusp (length string)) (let ((sign 1)) (cond ((find (aref string 0) "-–−") (setf sign -1 string (subseq string 1))) ((eql (aref string 0) #\+) (setf string (subseq string 1)))) (when (and (every #'(lambda (item) (or (char<= #\0 item #\9) (char= item decimal-separator))) string) (some #'(lambda (item) (char<= #\0 item #\9)) string) (<= 0 (count decimal-separator string) 1)) (let ((pos (position decimal-separator string))) (* sign (+ (number-string-to-integer (subseq string 0 pos)) (if pos (number-string-to-fractional (subseq string (1+ pos))) 0)))))))) |
From: Carlos K. <cko...@pi...> - 2010-11-11 05:53:18
|
On 11/10/2010 09:51 PM, Teemu Likonen wrote: > * 2010-11-10 23:09 (+0100), Slobodan Milnović wrote: > >> I have tried converting strings to numbers, and I have found the >> example using read-from-string. Unfortunately, it only accepts numbers >> formatted using decimal dot. >> >> Is there any kind of support for the number format using decimal >> comma? I have tried searching, but all I could find is the support for >> the various code pages. If not, is there an library that would provide >> the support for the various number formats? > > I have a function which reads a decimal number from string and turns it > to an exact number (not a floating point). Decimal separator character > can be changed with optional argument. > > (read-number-from-string "-1,2" #\,) > => -6/5 > > > (defun number-string-to-integer (string) > (handler-case (parse-integer string) > (t () nil))) > > > (defun number-string-to-fractional (string) > (loop > for i = 1/10 then (/ i 10) > for c across string > unless (char<= #\0 c #\9) return nil > sum (* i (position c "0123456789")))) > > > (defun read-number-from-string (string &optional (decimal-separator #\,)) > (setf string (string-trim '(#\Space #\Tab) string)) > (when (plusp (length string)) > (let ((sign 1)) > (cond ((find (aref string 0) "-–−") > (setf sign -1 > string (subseq string 1))) > ((eql (aref string 0) #\+) > (setf string (subseq string 1)))) > (when (and (every #'(lambda (item) > (or (char<= #\0 item #\9) > (char= item decimal-separator))) > string) > (some #'(lambda (item) > (char<= #\0 item #\9)) > string) > (<= 0 (count decimal-separator string) 1)) > (let ((pos (position decimal-separator string))) > (* sign (+ (number-string-to-integer (subseq string 0 pos)) > (if pos > (number-string-to-fractional > (subseq string (1+ pos))) > 0)))))))) I wanna play! Here's my functions for (defun string-to-real (string-rep) "Converts a string representation of a number to a rational representation." (let* ((string-parts (ppcre:split "\\." (string-trim '(#\Space #\Tab) string-rep))) (integer-portion (parse-integer (car string-parts) :junk-allowed t)) (fractional-portion (if (= (length string-parts) 1) 0 (parse-integer (cadr string-parts) :junk-allowed t))) (fractional-divisor (if (= (length string-parts) 1) 1 (expt 10 (length (cadr string-parts)))))) (+ integer-portion (/ fractional-portion fractional-divisor)))) (defun real-to-string (real-rep &key (places 2)) "Converts a rational representaion of a number into a string representation, rounded to `places' decimal places." (when real-rep (if (= places 0) (format nil "~a" (parse-integer (format nil "~,2f" real-rep) :junk-allowed t)) (format nil (format nil "~~,~af" places) (coerce real-rep 'long-float))))) (defun double-to-real (double-rep &key (places 2)) "Converts a double to a real. It does this by converting the double to a string, and then the string to a real. Decimal place truncation happens when converting to a string." (string-to-real (real-to-string double-rep :places places))) |
From: Christopher S. <cs...@dt...> - 2010-11-11 05:54:41
|
On Nov 10, 2010, at 10:57 PM, Pascal J. Bourguignon wrote: > Slobodan Milnović <slo...@gm...> writes: > >> I have tried converting strings to numbers, and I have found the >> example using read-from-string. Unfortunately, it only accepts numbers >> formatted using decimal dot. > > What do you mean? > > > * (mapcar 'read-from-string '("123" "123.456" "1e6" "#36rHelloWorld" "42.")) > > (123 123.456 1000000.0 1767707668033969 42) I think he is asking for locale-sensitive numeric parsing, in particular (parse-number "1,000" :locale 'numeric) => 1000 |
From: Slobodan M. <slo...@gm...> - 2010-11-11 08:02:07
|
On Thu, Nov 11, 2010 at 06:27, Christopher Stacy <cs...@dt...> wrote: > > On Nov 10, 2010, at 10:57 PM, Pascal J. Bourguignon wrote: > >> Slobodan Milnović <slo...@gm...> writes: >> >>> I have tried converting strings to numbers, and I have found the >>> example using read-from-string. Unfortunately, it only accepts numbers >>> formatted using decimal dot. >> >> What do you mean? >> >> >> * (mapcar 'read-from-string '("123" "123.456" "1e6" "#36rHelloWorld" "42.")) >> >> (123 123.456 1000000.0 1767707668033969 42) > > I think he is asking for locale-sensitive numeric parsing, > in particular (parse-number "1,000" :locale 'numeric) => 1000 Not exactly like that. Here in Croatia we are using decimal comma for representing real numbers - in this particular case that you have presented, for us the result would be 1 and not 1000. For example, let's take an monetary value, I think it would demonstrate exactly what the problem is. In the USA, it would be written something like this: $1,000,000.00 but we would write the same value like this: $1.000.000,00 And in this case the read-from-string that sbcl provides fails. Well, it works for countries that use decimal dot for the representation of the real numbers, but not for the rest of the world. :-) Well, it seems that if there is no locales support, it should be written. Perhaps I'll tackle that problem when I get a bit more lisp experience and free time. :-) For now, just printing out real numbers with decimal comma is good enough. :-) Thank you all for your examples, I will try them out! |
From: Raymond W. <rw...@gm...> - 2010-11-11 09:28:40
|
>From Henry Baker's "Pragmatic Parsing" paper: http://home.pipeline.com/~hbaker1/Prag-Parse.html --- it should be relatively easy to modify this to ignore a (configurable/parameterized) digit separator, and to have a (configurable/parameterized) decimal point character. BTW: Read this paper - it will do you good :-). In fact, read *all* Baker's papers. ============================= (deftype sign () '(member #\+ #\-)) (deftype expmarker () '(member #\e #\s #\f #\d #\l #\E #\S #\F #\D #\L)) (defun parse-number (&aux x (is #\+) id (i 0) dd (d 0) fd (f 0) (nf 0) (es #\+) ed (e 0) (m #\e)) ;;; Parse CL real number according to [Steele90,22.1.2] ;;; Return 2 values: the number and a reversed list of lookahead characters. (matchit [{[@(sign is) !(push is x)] []} ; scan sign. $[@(digit id) !(setq x nil i (+ (* i 10) (ctoi id)))] ; integer digits. {[!id #\/ !(push #\/ x) ; "/" => ratio. $[@(digit dd) !(setq x nil d (+ (* d 10) (ctoi dd)))]] ; denom. digits. [{[#\. {!id !(push #\. x)} ; decimal point. $[@(digit fd) !(setq x nil nf (1+ nf) f (+ (* f 10) (ctoi fd)))]] ; fract. digits. []} {[{!id !fd} @(expmarker m) !(push m x) ; exp. marker. {[@(sign es) !(push es x)] []} ; exponent sign. $[@(digit ed) !(setq x nil e (+ (* e 10) (ctoi ed)))]] ; exp. digits. []}]}]) (let ((sign (if (eql is #\-) -1 1)) (ex (if (eql es #\-) (- e) e))) (values (cond ((or fd ed) (make-float m sign i f nf ex)) ; see [Clinger90] (dd (/ (* sign i) d)) (id (* sign i)) (t nil)) x))) 2010/11/11 Slobodan Milnović <slo...@gm...>: > On Thu, Nov 11, 2010 at 06:27, Christopher Stacy <cs...@dt...> wrote: >> >> On Nov 10, 2010, at 10:57 PM, Pascal J. Bourguignon wrote: >> >>> Slobodan Milnović <slo...@gm...> writes: >>> >>>> I have tried converting strings to numbers, and I have found the >>>> example using read-from-string. Unfortunately, it only accepts numbers >>>> formatted using decimal dot. >>> >>> What do you mean? >>> >>> >>> * (mapcar 'read-from-string '("123" "123.456" "1e6" "#36rHelloWorld" "42.")) >>> >>> (123 123.456 1000000.0 1767707668033969 42) >> >> I think he is asking for locale-sensitive numeric parsing, >> in particular (parse-number "1,000" :locale 'numeric) => 1000 > > Not exactly like that. Here in Croatia we are using decimal comma for > representing real numbers - in this particular case that you have > presented, for us the result would be 1 and not 1000. > > For example, let's take an monetary value, I think it would > demonstrate exactly what the problem is. In the USA, it would be > written something like this: > > $1,000,000.00 > > but we would write the same value like this: > > $1.000.000,00 > > And in this case the read-from-string that sbcl provides fails. Well, > it works for countries that use decimal dot for the representation of > the real numbers, but not for the rest of the world. :-) > > Well, it seems that if there is no locales support, it should be > written. Perhaps I'll tackle that problem when I get a bit more lisp > experience and free time. :-) > > For now, just printing out real numbers with decimal comma is good enough. :-) > > Thank you all for your examples, I will try them out! > > ------------------------------------------------------------------------------ > Centralized Desktop Delivery: Dell and VMware Reference Architecture > Simplifying enterprise desktop deployment and management using > Dell EqualLogic storage and VMware View: A highly scalable, end-to-end > client virtualization framework. Read more! > http://p.sf.net/sfu/dell-eql-dev2dev > _______________________________________________ > Sbcl-help mailing list > Sbc...@li... > https://lists.sourceforge.net/lists/listinfo/sbcl-help > |
From: Slobodan M. <slo...@gm...> - 2010-11-11 11:49:31
|
2010/11/11 Raymond Wiker <rw...@gm...>: > From Henry Baker's "Pragmatic Parsing" paper: > http://home.pipeline.com/~hbaker1/Prag-Parse.html > > --- it should be relatively easy to modify this to ignore a > (configurable/parameterized) digit separator, and to have a > (configurable/parameterized) decimal point character. > > BTW: Read this paper - it will do you good :-). In fact, read *all* > Baker's papers. Thank you very much, I will. :-) |
From: <pj...@in...> - 2010-11-11 15:08:19
|
Slobodan Milnović <slo...@gm...> writes: > Not exactly like that. Here in Croatia we are using decimal comma for > representing real numbers - in this particular case that you have > presented, for us the result would be 1 and not 1000. Same in France. When the steam engine allowed to make trains crossing a country in less than a day, synchronization became important, and people in village finally decided to have a single hour country-wide. Now that we have the web allowing us to send written numbers all over the globe in less than a millisecond, perhaps it would be convenient to homogeneize the way we write numbers too? I vote to take american dot for decimal numbers, and have them take billion = 1e12 (n-illion = 1e(6*n). -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}. |
From: Tamas K P. <tk...@gm...> - 2010-11-11 15:52:02
|
On Thu, 11 Nov 2010 16:07:50 +0100, Pascal J. Bourguignon wrote: > Slobodan Milnović <slo...@gm...> writes: > >> Not exactly like that. Here in Croatia we are using decimal comma for >> representing real numbers - in this particular case that you have >> presented, for us the result would be 1 and not 1000. > > Same in France. > > When the steam engine allowed to make trains crossing a country in less > than a day, synchronization became important, and people in village > finally decided to have a single hour country-wide. > > Now that we have the web allowing us to send written numbers all over > the globe in less than a millisecond, perhaps it would be convenient to > homogeneize the way we write numbers too? > > I vote to take american dot for decimal numbers, and have them take > billion = 1e12 (n-illion = 1e(6*n). Agreed. Let them use milliard for 1e9! Now we just have to convince ~5-10e9 people to switch :-) Best, Tamas |
From: Slobodan M. <slo...@gm...> - 2010-11-13 17:32:11
|
There is one more question regarding numbers in SBCL. I don't understand this, and I need to have numbers with at least the precision of 8 decimal positions. This is SBCL 1.0.44.22, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. * (defvar pero 47.1234567) PERO * pero 47.123455 Where can I setup sbcl to stop rounding everything to 6 places? I have tried searching using google, but I couldn't find by which term should I search the solution. I've tried real numbers, rational numbers, float numbers, but I couldn't find anything except * |
From: Slobodan M. <slo...@gm...> - 2010-11-13 17:42:24
|
Eh, nevermind, I have found it: (setf *read-default-float-format* 'double-float) |
From: Christophe R. <cs...@ca...> - 2010-11-13 17:43:46
|
Slobodan Milnović <slo...@gm...> writes: > There is one more question regarding numbers in SBCL. I don't > understand this At this point, the best advice I can give you is to read and study carefully "What Every Computer Scientist Should Know about Floating Point", by David Goldberg; copies freely available all over the Internet. This explains the issues with floating point representation of numbers, which are used in SBCL (and in many, many other programming environments). Once you've read that, you will probably be led to a fixed point representation of numbers for your application. Cheers, Christophe |