2015-02-27 1 views
1

Когда я пытаюсь создать массив с одним поплавка, как это, я получаю:Создать массив с одним поплавком из double-float в lisp?

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

, я получаю следующее сообщение об ошибке:

The value 3.0 is not of type SINGLE-FLOAT 

Есть ли способ, чтобы создать массив с одной плавающей точкой от простого вектора двойного плавания?

ответ

2

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

Вы пытаетесь создать массив одного плавает (что говорит ваш текст) или массив дважды плавает (что предполагает код)? Чтобы создать массив из с двойными поплавками, вы должны использовать (make-array & hellip;: element-type 'double-float & hellip;), а для создания массива с одним поплавком, вы бы используйте (make-array & hellip;: element-type 'single-float & hellip;). Однако в любом случае элементы в исходном элементе должны соответствовать указанному типу; запись HyperSpec для make-array говорит, что:

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.

С одной-поплавком и двойным поплавком не тот же самый тип, вам необходимо заранее преобразовать данные. Вы можете использовать карту создать результат, или карту, записанными в, если вы хотите создать его первый, а затем скопировать результаты в Ев:.

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, что и предлагает ваш код. Если вы хотите просто массив одного поплавки, то вы можете просто правильный тип:

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) напрямую.

+0

Большое спасибо. Я приспосабливаю свой ответ для single-float, и он работает. – Xaving

+0

@ Что вы подразумеваете под его адаптацию? В вопросе вы попросили создать вектор двойных поплавков из вектора одиночных поплавков. Вот что делает этот код ... –

+0

Я спросил наоборот. Таким образом, в вашем решении все, что связано с двойным, я заменил его на один-float. – Xaving

3

Вы можете использовать вектор одиночных плаваний непосредственно:

#(3.0s0 4.0s0) 

Для сдвоенных поплавков используют:

#(3.0d0 4.0d0) 

по умолчанию тип чтения с плавающей точкой задается *read-default-float-format*. См. CLHS Chapter 2.3.2.2 (Syntax of a Float).

Edit: Это означает, что следующий делает то, что вы, кажется, хотят:

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

Если у вас есть много таких выражений в коде, связывание *read-default-float-format* глобально перед загрузкой затрагиваемых исходных файлов может быть целесообразным.

+0

Это обеспечивает вектор одиночных поплавков, но тип не будет специализирован для одиночных поплавков. –

+0

@JoshuaTaylor: да, но это не имеет значения для ': initial-contents'. Возможно, я должен быть более ясен. – Svante

+0

делает LET смысл? Может ли это повлиять на чтение поплавков в форме, которую она охватывает? –

Смежные вопросы