Почему создается Float32Array со смещением, которое не кратно размеру элемента, который не разрешен?

Я хотел бы прочитать двоичный файл с несколькими 32-битными значениями float при смещении байта 31.

К сожалению, new Float32Array(buffer, 31, 6); не работает. Смещение 32 вместо 31 работает, но мне нужно 31.

В соответствии с этой страницей смещение должно быть кратным размеру элемента, в этом случае 4.

Меня интересует причина такого поведения. Почему имеет значение, откуда начинается представление?

лучший обходной путь, который я нашел до сих пор, еще не превратился в gecko, поэтому я не могу его использовать.

Нужно ли мне перерезать и скопировать значения байтов в новый массив, чтобы получить мои значения float?

Ответ 1

Меня интересует причина такого поведения. Почему имеет значение, откуда начинается представление?

Некоторые архитектуры не допускают несвязанных доступов слов, и на архитектурах, которые позволяют это, например, на x86, есть штрафы за производительность (хотя некоторые команды должны быть выровнены).

Неужели мне нужно вырезать и копировать байтовые значения в новый массив, чтобы получить мои значения float?

Да, как и пример Маркуса, вы должны создать новый ArrayBuffer с представлением UInt8Array и представлением Float32Array для read_buffer (копировать с UInt8Array и интерпретировать из представления Float32Array), Затем вы можете прочитать ваши данные с помощью UInt8Array, скопировать его в представление read_buffer, а затем интерпретировать с помощью Float32Array. Это довольно бесшовный процесс.

Ответ 2

DataView.getFloat32() будет лучшим способом сделать это. DataView разработан для упакованных данных и позволяет осуществлять выравниваемый доступ к данным в ArrayBuffer, поэтому вы можете передавать с нечетными смещениями, такими как 31.

Ответ 3

Вы можете использовать slice, чтобы получить новый ArrayBuffer, содержимое которого является копией этого байта ArrayBuffer от начала, включительно, до конца

const buffer = new ArrayBuffer(250);
const list = buffer.slice(10); // index [11,250]
const nums = new Int32Array(list, 0, 60);