سؤال

على سبيل المثال، لدي هذه السلسلة:"6119726089.12814713"

إذا فعلت (string->number "6119726089.12814713") - باستخدام تنفيذ SISC والنتيجة هي 6.119726089128147e9 - وفي تنفيذ غيل هو 6119726089.128147 لكني أريد الرقم الدقيق مثل: 611972608912814713/100000000 دون خسارة الدقة.

أرغب في وظيفة مثل (سلسلة->دقيقة) أو شيء من هذا القبيل.

ملحوظة:الرجاء إصلاح لغتي الإنجليزية غير الأصلية وإزالة هذه الرسالة.شكرًا.

هل كانت مفيدة؟

المحلول

يستخدم (string->number "#e6119726089.12814713") لتحليل الرقم على وجه الدقة.هذا يعمل على الأقل لـ Racket and Guile.ومع ذلك، قد لا يعمل بشكل صحيح على تطبيقات النظام الأخرى؛ولهم الحرية في التحليل على أنه غير دقيق أولاً، ثم التحويل.


فيما يلي تطبيق محمول لـ 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))))))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top