如何将数字打印为具有指定格式的浮点数?

时间:2016-11-23 18:52:43

标签: format common-lisp coerce

任意数字都可以很容易地转换为浮点数,并带有一些小数位数。例如,使用(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用于此类输出还是格式足够?

2 个答案:

答案 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)

要使用coercefloat

强制数字浮动数字
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

请注意,浮动的精度有限 - 像往常一样。