JavaScript - конвертировать байты в float чистым способом - PullRequest
0 голосов
/ 31 августа 2018

Я недавно узнал, что могу преобразовать Float32 в массив байтов, которые его представляют - как таковой:

let number = Math.PI;
let bytes = new Uint8Array(new Float32Array([number]).buffer); // [219, 15, 73, 64]

Есть ли способ конвертировать bytes обратно в Float32, в чистом виде?

1 Ответ

0 голосов
/ 31 августа 2018

Есть ли способ конвертировать байты обратно в Float32

Вам не нужно конвертировать его, он уже там! вам просто нужно прочитать его из представления float32. Однако в вашем примере вы не сохранили ссылку на представление float32 ...

Типизированные массивы работают совсем не так, как другие числа в JavaScript. Ключ в том, чтобы думать о буфере и представлениях независимо, то есть Float32Array и Uint8Array - это просто представления в буфере (буфер - это просто непрерывный блок памяти фиксированного размера, поэтому типизированные массивы так быстро).

В вашем примере, когда вы вызывали new Float32Array, вы передали ему массив с одним числом для инициализации, но вы не передали ему буфер, это заставляет его создать для вас буфер соответствующей длины (4 байт). Когда вы вызываете new Uint8Array, вы передаете ему буфер вместо этого, это не заставляет его просто копировать буфер, а фактически использует его напрямую. Приведенный ниже пример эквивалентен вашему, но сохраняет все ссылки и делает приведенные выше утверждения более очевидными:

const number = Math.PI

const buffer = new ArrayBuffer(4);
const f32 = new Float32Array(buffer); // [0]
const ui8 = new Uint8Array(buffer); // [0, 0, 0, 0]

f32[0] = number;
f32 // [3.1415927410125732]
ui8 // [219, 15, 73, 64]

ui8[3] = 1;
f32 // [3.6929245196445856e-38]
ui8 // [219, 15, 73, 1]

Как вы можете видеть, нет необходимости "конвертировать" выше, поскольку оба представления совместно используют один и тот же буфер, любое изменение через одно представление мгновенно доступно в другом.

Это действительно хороший способ играть и понимать форматы с плавающей запятой. Также используйте ui8[i].toString(2), чтобы получить необработанный двоичный файл и используйте ui8[i] = parseInt('01010101', 2) set raw двоичный файл для каждого байта, где i равно 0-3. Обратите внимание, что вы не можете установить необработанный двоичный файл в представлении f32, поскольку он будет численно интерпретировать ваше число и разбить его на значения и экспоненты, однако вы можете захотеть сделать это, чтобы увидеть, как числовой двоичный файл преобразуется в формат float32.

...