An arbitrary number can be readily converted to float with some number of decimals. For example, using (format nil "~,2f" 6)
gives "6.00"
. But is there a way to directly coerce an arbitrary number using an analogous float type spec; i.e., outputting a number, not a string? Alternately, I've tried (read-from-string (format nil "~,2f" 6))
, but this does not retain the formatting.
I would like to print a nested tree containing numbers (along with other lisp objects), as floats with two decimal places. For example, a printout might look like X -> (A 3.00 (7.10 B) (C 8.12) 0.75)
regardless of the specific number types represented in X. Is set-pprint-dispatch used for this kind of output or is format sufficient?
Is set-pprint-dispatch used for this kind of output or is format sufficient?
Let's try with 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
Since the pretty-print dispatch table is copied before being modified, the function associated with floats is only called from inside the let-binding. When the return value of WRITE
is printed to the REPL, the default dispatch table is used. You could define a global variable to avoid recomputing the modified table each time you need it.
Note that if you don't give a value for :pretty
, then the special *PRINT-PRETTY*
variable defines whether the pretty-printer is used or not. For details see 22.2.1.4 Pretty Print Dispatch Tables.
I would like to print a nested tree containing numbers
If what you want is to output any number as a float, just dispatch on the REAL
type (complex numbers with non-zero imaginary parts can't be printed as you want, so I don't recommend dispatching on number
). Any necessary coercion will happen implicitly:
(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))
... writes:
(A 3.00 (7.10 B) (C 8.12) 0.75)