Frage

Zum Beispiel habe ich diese Zeichenfolge:"6119726089.12814713"

Wenn ich es tue (string->number "6119726089.12814713") - unter Verwendung der SISC-Implementierung ist das Ergebnis 6.119726089128147e9 - und in arglistiger Umsetzung ist 6119726089.128147 aber ich hätte gerne eine genaue Nummer, wie: 611972608912814713/100000000 ohne verlust präzision.

Ich hätte gerne eine Funktion wie (string->exact) oder so ähnlich.

BEACHTEN:bitte korrigieren Sie mein nicht muttersprachliches Englisch und entfernen Sie diese Nachricht.Danke.

War es hilfreich?

Lösung

Verwenden (string->number "#e6119726089.12814713") um die Zahl als genau zu analysieren.Dies funktioniert zumindest für Schläger und List.Bei anderen Schema-Implementierungen funktioniert es jedoch möglicherweise nicht richtig;es steht ihnen frei, zuerst als ungenau zu analysieren und dann zu konvertieren.


Hier ist eine tragbare Implementierung des string->exact funktion, nach der das OP gefragt hat.Ich habe es manuell mit einer Reihe von Eingaben getestet, aber Sie sollten Ihre eigenen Tests durchführen, um sicherzustellen, dass es Ihren Anforderungen entspricht:

(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))))))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top