在lisp中从double-float创建一个单浮点数组?

时间:2015-02-27 14:28:57

标签: lisp common-lisp sbcl

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

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

,我收到以下错误:

The value 3.0 is not of type SINGLE-FLOAT

有没有办法从double-float的简单向量创建单浮点数?

2 个答案:

答案 0 :(得分:3)

  

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

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

您是否正在尝试创建单浮点数(您的文字所说的)数组或双浮点数数组(代码建议的内容)?要创建一个双浮点数数组,你可以使用(make-array ...:element-type'double-float ...),并创建一个< strong>单浮点,你要使用(make-array ...:element-type'single-float ...)。但是,在任何一种情况下, initial-elements 参数中的元素都需要匹配指定的类型; make-array的HyperSpec条目表示:

  

initial-contents由嵌套的序列结构组成。该   结构中的级别数必须等于数组的级别。的每个   嵌套结构的叶子必须是由给定的类型   元件型

由于单浮点数和双浮点数不是同一类型,因此您需要事先转换数据。您可以使用地图来创建结果,或者 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)

这些示例假设您正在尝试创建一个双浮动数组,这是代码建议的内容。如果您只想要一个单浮点数数组,那么您可以使用正确的类型:

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

或者,作为Svante noted,您可以直接写#(3.0 4.0)#(3.0s0 4.0s0)

答案 1 :(得分:3)

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

#(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))

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