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)))))))) |