如何在 lisp 中以指定格式将数字打印为浮点数?
How to print numbers as floats with a specified format in lisp?
可以很容易地将任意数字转换为具有一定小数位数的浮点数。例如,使用 (format nil "~,2f" 6)
得到 "6.00"
。但是有没有办法使用类似的浮点类型规范直接强制任意数字?即,输出一个数字,而不是一个字符串?或者,我试过 (read-from-string (format nil "~,2f" 6))
,但这不保留格式。
我想打印一个包含数字(以及其他 lisp 对象)的嵌套树,作为带有两位小数的浮点数。例如,无论 X 中表示的特定数字类型如何,打印输出可能看起来像 X -> (A 3.00 (7.10 B) (C 8.12) 0.75)
。set-pprint-dispatch 是否用于此类输出或格式是否足够?
要将数字强制转换为浮点数,请使用 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
请注意,浮点数的精度有限 - 和往常一样。
Is set-pprint-dispatch used for this kind of output or is format sufficient?
让我们试试 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
由于漂亮打印调度 table 在被修改之前被复制,与 float 关联的函数只能从 let-binding 内部调用。当 WRITE
的 return 值被打印到 REPL 时,使用默认调度 table。您可以定义一个全局变量,以避免每次需要时重新计算修改后的 table。
请注意,如果您不为 :pretty
提供值,那么特殊的 *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
如果你想要输出任何数字作为一个浮点数,只需调度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)
可以很容易地将任意数字转换为具有一定小数位数的浮点数。例如,使用 (format nil "~,2f" 6)
得到 "6.00"
。但是有没有办法使用类似的浮点类型规范直接强制任意数字?即,输出一个数字,而不是一个字符串?或者,我试过 (read-from-string (format nil "~,2f" 6))
,但这不保留格式。
我想打印一个包含数字(以及其他 lisp 对象)的嵌套树,作为带有两位小数的浮点数。例如,无论 X 中表示的特定数字类型如何,打印输出可能看起来像 X -> (A 3.00 (7.10 B) (C 8.12) 0.75)
。set-pprint-dispatch 是否用于此类输出或格式是否足够?
要将数字强制转换为浮点数,请使用 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
请注意,浮点数的精度有限 - 和往常一样。
Is set-pprint-dispatch used for this kind of output or is format sufficient?
让我们试试 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
由于漂亮打印调度 table 在被修改之前被复制,与 float 关联的函数只能从 let-binding 内部调用。当 WRITE
的 return 值被打印到 REPL 时,使用默认调度 table。您可以定义一个全局变量,以避免每次需要时重新计算修改后的 table。
请注意,如果您不为 :pretty
提供值,那么特殊的 *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
如果你想要输出任何数字作为一个浮点数,只需调度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)