任意数字都可以很容易地转换为浮点数,并带有一些小数位数。例如,使用(format nil "~,2f" 6)
可以"6.00"
。但有没有办法使用类似的浮点型规范直接强制任意数字;即,输出一个数字,而不是一个字符串?或者,我已尝试(read-from-string (format nil "~,2f" 6))
,但这不会保留格式。
我想打印一个包含数字的嵌套树(以及其他lisp对象),作为带有两个小数位的浮点数。例如,打印输出可能看起来像X -> (A 3.00 (7.10 B) (C 8.12) 0.75)
,无论X中表示的具体数字类型是什么.set-pprint-dispatch用于此类输出还是格式足够?
答案 0 :(得分:2)
set-pprint-dispatch用于这种输出还是格式足够?
让我们试试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
由于在修改之前复制了漂亮的打印调度表,因此只能从let-binding内部调用与float相关联的函数。将WRITE
的返回值打印到REPL时,将使用默认的调度表。您可以定义一个全局变量,以避免每次需要时重新计算修改后的表。
请注意,如果您没有为:pretty
提供值,则特殊*PRINT-PRETTY*
变量会定义是否使用漂亮的打印机。有关详细信息,请参阅22.2.1.4 Pretty Print Dispatch Tables。
我想打印一个包含数字的嵌套树
如果你想要的是输出任何数字作为浮点数,只需在REAL
类型上发送(具有非零虚部的复数不能打印出你想要的,所以我不建议在number
上发送。任何必要的强制都会隐含地发生:
(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))
...写道:
(A 3.00 (7.10 B) (C 8.12) 0.75)
答案 1 :(得分:1)
要使用coerce
或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
请注意,浮动的精度有限 - 像往常一样。