2012-08-16 8 views
5

Kann jemand die Anzahl der Nachkommastellen für einen Float in Lisp angeben?LISP - Nachkommastellen

sagen, wenn ich diesen Befehl an der REPL drucken:

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

ich:

0.142857150000000 

Aber die Zahl wird an der 8. Stelle nach dem Komma gerundet, ich brauche ein, um zu sehen viele Ziffern nach dem Komma, um zu sehen, ob die Zahl zyklisch ist und um die Periode zu berechnen. (Eigentlich fange ich an zu versuchen, Project Eulers Problem 26 zu lösen).

brauche ich so etwas zu bekommen:

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

Danke,

Luca

Antwort

17

Common Lisp hat nicht schwimmt mit beliebiger Genauigkeit in seinem Standard.

Common Lisp definiert vier Float-Typen in der Norm: SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT, LONG-FLOAT.

Sie können ein Verhältnis mit einem Schwimmer zwingen die Funktion COERCE (Beispiel in LispWorks) mit:

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

oder als LONG-FLOAT in CLISP

mit mehr Float-Zahlen berechnen Sie brauchen Erweiterungen zu Common Lisp. GNU CLISP hat eine nicht-portable Erweiterung und können die Anzahl der (binär) Ziffern gesetzt:

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

Beispiel:

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

Danke, das war wirklich hilfreich. – Luca

3

Neben Rainer ausgezeichnete Antwort, Ich glaube, Sie überprüfen möchten aus der Funktion RATIONALIZE:

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

Sie auch Division von Hand tun kann, wo würden Sie st krank Notwendigkeit Werte länger als lange lange lange (was für einige Compiler zu lang sein, ist bekannt;) So etwas wie folgt aus:

(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 

Es könnte effizienter Art und Weise sein, den Bruchteil zu berechnen, aber sie sind zu komplex (für mich, und wäre für dieses Beispiel).