1

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

4

2 回答 2

2

要将数字强制为浮点数,请使用coerceor 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

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

于 2016-11-23T19:58:32.097 回答
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 内部调用。当 的返回值WRITE打印到 REPL 时,使用默认的调度表。您可以定义一个全局变量以避免每次需要时重新计算修改后的表。

请注意,如果您不给 值:pretty,则特殊*PRINT-PRETTY*变量定义是否使用漂亮打印机。有关详细信息,请参阅22.2.1.4 漂亮打印调度表

我想打印一个包含数字的嵌套树

如果您想要将任何数字输出为浮点数,只需在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)
于 2016-11-24T08:34:36.600 回答