Pergunta

Por exemplo, eu tenho esta string:"6119726089.12814713"

Se eu fizer (string->number "6119726089.12814713") - usando a implementação SISC o resultado é 6.119726089128147e9 - e no Guile a implementação é 6119726089.128147 mas eu gostaria de um número exato, como: 611972608912814713/100000000 sem perda de precisão.

Eu gostaria de uma função como (string->exato) ou algo assim.

OBSERVAÇÃO:corrija meu inglês não nativo e remova esta mensagem.Obrigado.

Foi útil?

Solução

Usar (string->number "#e6119726089.12814713") para analisar o número como exato.Isso funciona pelo menos para Racket e Guile.Entretanto, pode não funcionar corretamente em outras implementações do Scheme;eles têm a liberdade de primeiro analisar como inexatos e depois converter.


Aqui está uma implementação portátil do string->exact função que o OP solicitou.Eu testei manualmente com uma variedade de entradas, mas você deve fazer seus próprios testes para garantir que ele atenda às suas necessidades:

(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))))))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top