كيف يمكنني تحويل سلسلة إلى رقم دقيق في Scheme Lisp؟
سؤال
على سبيل المثال، لدي هذه السلسلة:"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))))))