Как я могу упаковать одно 4-битное и два 10-битных целых числа в UintArray(3), а затем прочитать их обратно в JavaScript?

Я пытаюсь упаковать 4-битное число (0–15), за которым следуют два 10-битных числа (0–1023), в UintArray(3).

Например: 15, 1023, 1023.

Я могу прочитать первое 4-битное число и последнее 10-битное число.

Но я не могу понять, как читать/записывать среднее 10-битное число.

function writeInt4_10_10(arr, off, a, b, c) {
  arr[off + 0] = (a << 4) & 0xf0 | (b >> 4) & 0x0f;
  arr[off + 1] = (b << 6) & 0xfc | (c >> 8) & 0x03;
  arr[off + 2] = (c << 0) & 0xff;
}

function readInt4_10_10(arr, off) {
  var a = (arr[off + 0] & 0xf0) >> 4;
  var b = (arr[off + 0] & 0x0f) << 6 | (arr[off + 1] & 0xfc) >> 4;
  var c = (arr[off + 1] & 0x03) << 8 | (arr[off + 2] & 0xff) >> 0;
  return [a, b, c];
}

var buf = new Uint8Array(3);
writeInt4_10_10(buf, 0, 13, 1001, 999)
var r = readInt4_10_10(buf, 0);
console.info(r)
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
0
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Метод записи имеет неправильные смещения смещения. Чтобы превратить старшие 4 бита из 10-битного b в младшие 4 бита arr[0], их нужно сдвинуть на 6. А чтобы превратить младшие 6 бит b в старшие 6 бит из 8-битного arr[1], они нужно сдвинуть на 2:

function writeInt4_10_10(arr, off, a, b, c) {
  arr[off + 0] = (a << 4) & 0xf0 | (b >> 6) & 0x0f;
//                                       ^
  arr[off + 1] = (b << 2) & 0xfc | (c >> 8) & 0x03;
//                     ^
  arr[off + 2] = (c << 0) & 0xff;
}

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

function readInt4_10_10(arr, off) {
  var a = (arr[off + 0] & 0xf0) >> 4;
  var b = (arr[off + 0] & 0x0f) << 6 | (arr[off + 1] & 0xfc) >> 2;
//                                                              ^
  var c = (arr[off + 1] & 0x03) << 8 | (arr[off + 2] & 0xff) >> 0;
  return [a, b, c];
}

Короче говоря, вам нужна эта строка в вашей процедуре записи:

arr[off + 1] = (b & 0x3f) << 2 | (c >> 8) & 0x03;

И эта строка в вашей процедуре чтения:

var b = (arr[off + 0] & 0x0f) << 6 | (arr[off + 1] & 0xfc) >> 2;

Собираем все это вместе.

function writeInt4_10_10(arr, off, a, b, c) {
  arr[off + 0] = (a << 4 & 0xf0) | (b >> 6 & 0x0f);
  arr[off + 1] = (b & 0x3f) << 2 | (c >> 8) & 0x03;
  arr[off + 2] = (c << 0) & 0xff;
}

function readInt4_10_10(arr, off) {
  var a = (arr[off + 0] & 0xf0) >> 4;
  var b = (arr[off + 0] & 0x0f) << 6 | (arr[off + 1] & 0xfc) >> 2;
  var c = (arr[off + 1] & 0x03) << 8 | (arr[off + 2] & 0xff) >> 0;
  return [a, b, c];
}

var buf = new Uint8Array(3);
writeInt4_10_10(buf, 0, 13, 1001, 999)
var r = readInt4_10_10(buf, 0);
console.info(r)

Проблема, с которой вы столкнулись, в основном связана с хранением данных по индексу 1. Для ваших чисел 13, 1001, 999 у нас есть следующее в двоичном виде:

00001101 | 1111101001 | 1111100111

И для упаковки в Uint8Array, как вы описали, нам нужна следующая договоренность:

11011111 | 10100111 | 11100111

Итак, проблема с вашим кодом в процедуре записи заключается в том, что вы сместили b << 6 без предварительного удаления первых 4 двоичных цифр с помощью битовой маски. 0x3f — это маска, которая вам нужна для этой цели. Вам нужно всего лишь сдвинуть результат & 0x3f на 2, чтобы эти биты оказались в правильном положении.

Что касается процедуры чтения, вы почти были там, но не переложили соответствующую сумму на var b. (arr[off + 1] & 0xfc) — правильная идея, но эта маска удаляет две цифры, поэтому вам следует сдвинуть результат только на 2.

Большое спасибо h0r53 за подробное объяснение. Я очень ценю помощь

Unwarped 02.06.2024 01:57

Другие вопросы по теме