1

例如,我有这个字符串:“6119726089.12814713”

如果我这样做(string->number "6119726089.12814713")- 使用 SISC 实现,结果是6.119726089128147e9- 在 Guile 实现中是6119726089.128147,但我想要一个确切的数字,比如:611972608912814713/100000000不损失精度。

我想要一个像 (string->exact) 这样的函数或类似的函数。

注意:请修复我的非母语英语并删除此消息。谢谢。

4

1 回答 1

3

用于(string->number "#e6119726089.12814713")准确解析数字。这至少适用于 Racket 和 Guile。但是,它可能无法在其他 Scheme 实现上正常工作;他们可以自由地首先解析为不精确,然后进行转换。


string->exact这是 OP 要求的功能的可移植实现。我已经使用一系列输入手动测试了它,但您应该自己进行测试以确保它符合您的需求:

(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))))))
于 2014-04-12T06:40:53.510 回答