Wie kann ich eine Zeichenfolge in Schema Lisp in eine exakte Zahl konvertieren?
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.
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))))))