2016-11-23 1 views
0

Eine beliebige Zahl kann mit einigen Dezimalzahlen in Float umgewandelt werden. Zum Beispiel ergibt (format nil "~,2f" 6)"6.00". Aber gibt es eine Möglichkeit, eine beliebige Zahl mit einer analogen Float-Typ-Spezifikation direkt zu erzwingen; d.h. Ausgabe einer Nummer, nicht einer Zeichenkette? Alternativ habe ich versucht (read-from-string (format nil "~,2f" 6)), aber dies behält nicht die Formatierung.Wie man Zahlen als Schwimmer mit einem bestimmten Format druckt?

Ich möchte einen verschachtelten Baum mit Zahlen (zusammen mit anderen Lisp-Objekten) als Float mit zwei Dezimalstellen drucken. Beispielsweise könnte ein Ausdruck wie X -> (A 3.00 (7.10 B) (C 8.12) 0.75) aussehen, unabhängig von den in X dargestellten spezifischen Zahlentypen. Wird für diese Art der Ausgabe set-pprint-dispatch verwendet oder ist das Format ausreichend?

+3

Ich glaube, du verwechselst eine Nummer mit der gedruckten Darstellung. – sds

+1

Meinst du, dass Sie eine ganze Zahl in einen Float erzwingen wollen? Wie in '(float 6)' => '6.0'? Was meinst du mit "Formatierung beibehalten"? Zahlen im Speicher enthalten keine Formatierung. Sie können eine beliebige Zahl so formatieren, wie Sie möchten, wenn Sie sie drucken. – jkiiski

+0

@sds Ja, jetzt sehe ich, dass Sie Recht haben. Was ich wirklich versuche, ist eine Nummer ohne die Anführungszeichen auszudrucken. Ich sollte nur verwenden (formatieren t "~, 2f" 6) statt (format nil "~, 2f" 6). Danke fürs klarstellen. – davypough

Antwort

2

Wird für diese Art von Ausgabe set-pprint-dispatch verwendet oder ist das Format ausreichend?

Lassen Sie uns versuchen, mit SET-PPRINT-DISPATCH:

CL-USER> (let ((*print-pprint-dispatch* (copy-pprint-dispatch))) 
      (set-pprint-dispatch 'float (lambda (s f) (format s "~,2f" f))) 
      (write '(A 3.00 (7.10 B) (C 8.12) 0.75) :pretty t)) 

(A 3.00 (7.10 B) (C 8.12) 0.75) ;; standard output 
(A 3.0 (7.1 B) (C 8.12) 0.75) ;; result printed by the REPL 

Da die Pretty-Print-Dispatch-Tabelle, bevor sie geändert kopiert wird, wird die Funktion mit Schwimmern verbunden ist, nur aus dem Inneren des let-Bindung genannt. Wenn der Rückgabewert WRITE an die REPL gedruckt wird, wird die Standardversandtabelle verwendet. Sie könnten eine globale Variable definieren, um zu vermeiden, dass die geänderte Tabelle jedes Mal neu berechnet wird, wenn Sie sie benötigen. Wenn Sie für :pretty keinen Wert angeben, legt die spezielle Variable fest, ob der Pretty-Drucker verwendet wird oder nicht. Für Details siehe 22.2.1.4 Pretty Print Dispatch Tables.

Ich möchte eine verschachtelte Baum Zahlen enthalten

Wenn das, was Sie ausgeben möchten drucken eine beliebige Anzahl als Schwimmer ist, versenden Sie einfach auf den REAL Typ (komplexe Zahlen mit nicht-Null Imaginäre Teile können nicht gedruckt werden, wie Sie wollen, daher empfehle ich nicht, auf number zu versenden. Eventuell notwendige Zwang geschehen wird implizit:

(let ((*print-pprint-dispatch* (copy-pprint-dispatch))) 
    (set-pprint-dispatch 'real (lambda (s f) (format s "~,2f" f))) 
    (write '(A 3 (7.1d0 B) (C 203/25) #C(3/4 0)) :pretty t)) 

... schreibt:

(A 3.00 (7.10 B) (C 8.12) 0.75) 
+1

Die Anwendung hierfür ist ein zusammenfassender Ausdruck, also funktioniert es großartig. Ich habe 'in-package' Statements vor und nach' hinzugefügt write', um das Drucken des Paketpräfixes für Nicht-Reals zu unterdrücken, und die 'write'-Anweisung in eine Schleife eingebettet, um jedes Element in der obersten Ebene des Eingabebaums in einer separaten Zeile zu drucken. (Bitte erläutern Sie weiter, ob es sich um Änderungen handelt) Danke, dass Sie mir dabei geholfen haben, darüber nachzudenken. – davypough

+0

Gern geschehen, danke, Sie können '* package *' lokal binden, anstatt 'in-package' zu ​​verwenden, was einfacher ist, weil Sie es nicht müssen Zurück zum vorherigen Paket explizit, die fehleranfällig sein könnte. Aber ich würde lieber ': escape' zu ​​NIL im Aufruf zu schreiben, um das Drucken von Paketen zu vermeiden. Siehe http://clhs.lisp.se/Body/v_pr_esc .htm # STprint-escapeST. Sie können auch benutzerdefinierte hübsche Druckerfunktionen für Symbole definieren, wie für Zahlen. – coredump

1

Zahlen zu zwingen, Zahlen zu schweben verwenden coerce oder float:

CL-USER 121 > (float 2/3 1.0s0) 
0.6666667 

CL-USER 122 > (float 2/3 1.0d0) 
0.6666666666666666D0 

CL-USER 123 > (coerce 2/3 'double-float) 
0.6666666666666666D0 

Beachten Sie, dass Präzision haben nur begrenzte schwimmt - wie üblich.

Verwandte Themen