在 lisp 中从双浮点数创建一个单浮点数数组?

Create an array of single-float from double-float in lisp?

当我尝试创建这样的单浮点数组时,我得到:

(make-array 2 :element-type 'single-float :initial-contents #(3.0 4.0))

,我收到以下错误:

The value 3.0 is not of type SINGLE-FLOAT

有没有办法从一个简单的双浮点向量创建一个单浮点数组?

When I try to create a single-float array like this, i get:

(make-array 2 :element-type 'double-float :initial-contents #(3.0 4.0))

您是要创建一个 单浮点数 数组(如您的文字所述)还是 双浮点数 数组(代码建议什么)?要创建一个 double-floats 数组,您可以使用 (make-array … :element-type 'double-float …),以及要创建一个 single-floats 数组,你可以使用 (make-array … :element-type 'single-float …)。但是,无论哪种情况,initial-elements 参数中的元素都需要匹配指定的类型; make-array 的 HyperSpec 条目说:

initial-contents is composed of a nested structure of sequences. The numbers of levels in the structure must equal the rank of array. Each leaf of the nested structure must be of the type given by element-type.

由于单浮点数和双浮点数不是同一类型,因此您需要事先转换数据。您可以使用 map 来创建结果,或者如果您想先创建它然后将结果复制到 map-into 中。例如:

CL-USER> (map '(vector double-float *)
         #'(lambda (x) (float x 1.0d0))
         #(3.0 4.0))
#(3.0d0 4.0d0)

CL-USER> (map-into (make-array 2 :element-type 'double-float)
                   #'(lambda (x) (float x 1.0d0))
                   #(3.0 4.0))
#(3.0d0 4.0d0)

这些示例假设您正在尝试创建一个 double-floats 数组,这正是您的 code 所建议的。如果你只想要一个 单浮点数 的数组,那么你可以只需要正确的类型:

CL-USER> (make-array 2 :element-type 'single-float :initial-contents #(3.0 4.0))
#(3.0 4.0)

或者,如,你可以只写#(3.0 4.0)#(3.0s0 4.0s0)直接。

您可以直接使用单个浮点数的向量:

#(3.0s0 4.0s0)

对于双浮点数使用:

#(3.0d0 4.0d0)

默认的读取浮点类型由*read-default-float-format*给出。参见 CLHS Chapter 2.3.2.2 (Syntax of a Float)

编辑: 这意味着以下内容可以满足您的要求:

(make-array 2 :element-type 'single-float :initial-contents #(3.0s0 4.0s0))

如果您的代码中有 很多 此类表达式,在加载受影响的源文件之前全局绑定 *read-default-float-format* 可能是值得的。