Question

Par exemple, j'ai cette chaîne :"6119726089.12814713"

Si je fais (string->number "6119726089.12814713") - en utilisant l'implémentation SISC, le résultat est 6.119726089128147e9 - et dans la mise en œuvre de Guile est 6119726089.128147 mais j'aimerais un nombre exact, comme : 611972608912814713/100000000 sans perte de précision.

Je voudrais une fonction comme (string->exact) ou quelque chose comme ça.

NOTE:veuillez corriger mon anglais non natif et supprimer ce message.Merci.

Était-ce utile?

La solution

Utiliser (string->number "#e6119726089.12814713") pour analyser le nombre comme exact.Cela fonctionne au moins pour Racket et Guile.Cependant, il se peut qu'il ne fonctionne pas correctement sur d'autres implémentations de Scheme ;ils sont libres d'analyser d'abord comme inexact, puis de convertir.


Voici une implémentation portable de string->exact fonction demandée par le PO.Je l'ai testé manuellement avec une gamme d'entrées, mais vous devez effectuer vos propres tests pour vous assurer qu'il répond à vos besoins :

(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))))))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top