2012-08-16 26 views
5

क्या कोई जानता है कि लिस्प में फ्लोट के लिए दशमलव बिंदु के बाद अंकों के अंक को कैसे निर्दिष्ट किया जाए?LISP - दशमलव बिंदु के बाद अंक

कहते हैं कि अगर मैं आरईपीएल पर इस आदेश को मुद्रित:

CL-USER 3 > (format t "~,15f" (float (/ 1 7))) 

मैं:

0.142857150000000 

लेकिन संख्या दशमलव बिंदु के बाद 8 वीं अंकों पर गोल है, मैं एक देखने की जरूरत यह देखने के लिए कि क्या संख्या चक्रीय है और अवधि की गणना करने के लिए दशमलव बिंदु के बाद बहुत सारे अंक हैं। (असल में मैं प्रोजेक्ट यूलर की समस्या को हल करने और हल करने के लिए शुरू कर रहा हूं 26)।

मैं कुछ इस तरह प्राप्त करने की आवश्यकता:

CL-USER 3 > (format t "~,15f" (float (/ 1 7))) 
0.142857142857142857142857142857142857.... 

धन्यवाद,

लुका

उत्तर

17

कॉमन लिस्प अपने मानक में मनमाने ढंग से शुद्धता के साथ तैरता नहीं है।

आम लिस्प मानक में चार फ्लोट प्रकार परिभाषित करता है: SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT, LONG-FLOAT

आप समारोह COERCE (LispWorks में उदाहरण) का उपयोग कर एक नाव के लिए एक अनुपात विवश कर सकते हैं:

CL-USER 1 > (coerce (/ 1 7) 'double-float) 
0.14285714285714285D0 

या के रूप में एक LONG-FLOAT CLISP

में

अब नाव नंबर आप की जरूरत के साथ परिकलन करने हेतु सामान्य लिस्प के लिए एक्सटेंशन। GNU CLISP एक गैर पोर्टेबल एक्सटेंशन है और (बाइनरी) अंकों की संख्या निर्धारित कर सकते हैं:

(SETF (EXT:LONG-FLOAT-DIGITS) n)

उदाहरण:

[3]> (SETF (EXT:LONG-FLOAT-DIGITS) 1000)  
1000 
[4]> (coerce (/ 1 7) 'long-float) 
0.142857142857142857142857142857142857142857142857142857 
142857142857142857142857142857142857142857142857142857 
142857142857142857142857142857142857142857142857142857 
142857142857142857142857142857142857142857142857142857 
142857142857142857142857142857142857142857142857142857 
142857142857142857142857142857142857143L0 
+0

धन्यवाद, यह वास्तव में सहायक था। – Luca

3

रेनर उत्तम जवाब के अलावा, मुझे लगता है कि आप जाँच करना चाहते हैं समारोह RATIONALIZE आउट:

(rationalize (float 1/7)) 
1/7 
3

तुम भी हाथ, द्वारा विभाजन कर सकते हैं जहां सेंट होगा बीमार की जरूरत मान अब तो लंबे लंबे (जो जाना जाता है कुछ compilers के लिए बहुत लंबा होने के लिए;) इस तरह:

(defun divide (a b &key (precision 8)) 
    (let ((fractional 0)) 
    (multiple-value-bind (whole reminder) 
     (floor a b) 
     (unless (zerop reminder) 
     (dotimes (i precision) 
      (setf reminder (* reminder 10)) 
      (multiple-value-bind (quot rem) 
       (floor reminder b) 
      (setf fractional (+ (* fractional 10) quot)) 
      (when (zerop rem) (return)) 
      (setf reminder rem)))) 
     (values whole fractional)))) 

(multiple-value-call #'format t "~d.~d~&" (divide 1 7)) 
(multiple-value-call #'format t "~d.~d~&" (divide 1 7 :precision 54)) 

;; 0.14285714 
;; 0.142857142857142857142857142857142857142857142857142857 

वहाँ और अधिक कुशल तरीके आंशिक हिस्सा गणना करने के लिए हो सकता है, लेकिन वे बहुत जटिल हैं (मेरे लिए, और इस उदाहरण के लिए होगा)।