1

For example, I have this string: "6119726089.12814713"

If I do (string->number "6119726089.12814713") - using the SISC implementation the result is 6.119726089128147e9 - and in Guile implementation is 6119726089.128147 but I would like an exact number, like: 611972608912814713/100000000 without loss precision.

I'd like a function like (string->exact) or something like this.

NOTE: please fix my non-native English and remove this message. Thanks.

Felipe
  • 16,649
  • 11
  • 68
  • 92

1 Answers1

3

Use (string->number "#e6119726089.12814713") to parse the number as exact. This works for at least Racket and Guile. It may not work correctly on other Scheme implementations, however; they are at liberty to parse as inexact first, then convert.


Here's a portable implementation of the string->exact function that the OP asked for. I've manually tested it with a range of inputs, but you should do your own testing to ensure it fits your needs:

(define (string->exact str)
  (define zero (char->integer #\0))
  (let loop ((result #f)
             (factor 1)
             (seen-dot? #f)
             (digits (string->list str)))
    (if (null? digits)
        (and result (/ result factor))
        (let ((cur (car digits))
              (next (cdr digits)))
          (cond ((and (not result) (not seen-dot?) (char=? cur #\-))
                 (loop result (- factor) seen-dot? next))
                ((and (not seen-dot?) (char=? cur #\.))
                 (loop result factor #t next))
                ((char<=? #\0 cur #\9)
                 (loop (+ (* (or result 0) 10) (- (char->integer cur) zero))
                       (if seen-dot? (* factor 10) factor)
                       seen-dot? next))
                (else #f))))))
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • Thank you very much! It works very fine on Guile: 611972608912814713/100000000. But why not in SISC? In SISC the result is 305986304456407356262207031/50000000000000000 which is 6119726089.12814712524414062 - Do you know why? – Felipe Apr 12 '14 at 06:57
  • 1
    It sounds like SISC parsed the number as inexact first, then converted it to exact "after the fact". :-( I think that's buggy behaviour, but technically (if I remember correctly), the standard allows this. Meh. – C. K. Young Apr 12 '14 at 06:59
  • Reference: http://groups.csail.mit.edu/mac/ftpdir/scheme-reports/r5rs-html/r5rs_8.html#SEC54 – Felipe Apr 18 '14 at 09:52
  • 1
    @FelipeMicaroniLalli I finally got around to writing a portable implementation of the `string->exact` function you're hoping to see. Granted, it's nearly 3 years late, but I hope you find it useful anyway. :-) – C. K. Young Jan 04 '17 at 04:56