Конверсия между видами Бигаррэй - PullRequest
0 голосов
/ 25 февраля 2020

Учитывая эти 3 больших массива:

open Bigarray
let arr_float32 = Array1.of_array Float32 c_layout [|42.0|]
let arr_uint8 = Array1.of_arrayInt8_unsigned c_layout [|42|]
let arr_float32_as_uint8 = Array1.of_array Int8_unsigned c_layout [|0; 0; 40; 66|]
  1. Есть ли способ приведения arr_float32, чтобы сделать его (по типу и по значению) равным arr_uint8?
  2. Есть ли способ переосмысления arr_float32, чтобы сделать его равным (по типу и значению) arr_float32_as_uint8?

[|0; 0; 40; 66|], являющимся представлением с прямым порядком байтов 42.0

Ответы [ 2 ]

0 голосов
/ 26 февраля 2020

Вы пытаетесь изменить тип значения. Это то, что действительно не допускается системой типов. Система типов существует специально, поэтому вы не можете сделать это (случайно).

Тем не менее иногда есть причины, по которым нужно это делать. Обычно для производительности. Функция для этого Obj.magic : 'a -> 'b. Как показывает тип, Obj.magi c принимает любой тип и выводит любой другой тип. Он меняет тип как на волхвов c. :)

Это следует делать только в точно контролируемых ситуациях. Вы должны знать, что вы делаете, и это нормально делать при использовании Obj.magi c. Лучше всего аннотировать типы вокруг Obj.magi c настолько явно, насколько это возможно, чтобы вы не получили никаких случайных результатов. В вашем случае укажите тип для ввода и вывода Bigarrays.

Внутренне Bigarrays - это просто блок памяти с некоторым подсчетом ссылок для операций среза. Для методов get / set, оптимизирующих в зависимости от типа массива, используется некий компилятор magi c. Поэтому доступ к массиву должен быть правильно выровнен по типу, к которому вы обращаетесь Например, не пытайтесь получить подмассив со смещением 1 массива int8 и обращаться к нему как с плавающей точкой. Это не удастся на многих процессорах. Но использование их прямо должно работать.

Позвольте мне повторить это: остерегайтесь того, что вы делаете что-то, чтобы обойти систему типов. Obj.magi c вообще не проверяет, что вы делаете что-то вменяемое. Твоя работа - знать, что ты там делаешь. Я уже разыграл Bigarrays с помощью Obj.magi c и считаю, что это безопасно. Если я ошибаюсь, то это должно быстро sh, поскольку Obj.magi c обычно не выживает при неправильном использовании.

0 голосов
/ 25 февраля 2020

Обычный смысл приведения (IMHO) - создавать новое значение, а не изменять значение чего-либо. Другими словами, ваш первый вопрос просто спрашивает, есть ли способ вычислить этот новый большой массив. Есть способ вычислить его, создав новый bigarray и используя int_of_float для каждого элемента исходного массива.

Нет способа переосмыслить значения в bigarray (или любые значения в OCaml, на самом деле) не выходя за пределы языка, чтобы пробить абстракцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...