Реализация динамических битовых полей - PullRequest
0 голосов
/ 30 декабря 2011

Дело в том, что может произойти в следующей задаче.

-Элементы массива int, скажем, длиной 5, 5, 6, 7, 9 бит (они разные).

Как я могу его кодировать, чтобы он занимал 32 бита вместо обычных 160 бит?

Я также хочу сказать, что на другой стороне (стороне декодирования) я не знаю, насколько велик каждый элемент. Итак, как я могу декодировать, если я получаю такие данные, или, другими словами, как я могу кодировать изначально таким способом, который может быть легко декодирован?

Ответы [ 3 ]

2 голосов
/ 30 декабря 2011

Если распределение битов между этими числами известно заранее, это просто: просто поместите биты каждого элемента в массиве в правильную позицию в результирующем int, например так (например, в коде C ++):

unsigned int encoded = (val[0]) | (val[1] << 5) | (val[2] << 10) |
              (val[3] << 16) | (val[4] << 23);

... при условии, что val является массивом типа int и содержит числа длиной 5, 5, 6, 7 и 9 бит.Декодирование одинаково просто:

int decoded[5];
decoded[0] = encoded & 0x1F;
decoded[1] = (encoded >> 5) & 0x1F;
decoded[2] = (encoded >> 10) & 0x3F;
decoded[3] = (encoded >> 16) & 0x7F;
decoded[4] = (encoded >> 23);

Если длины битов не известны заранее, и единственный известный факт, что их объединенный размер битов равен 32, то для общего случая этоневозможно закодировать их максимум в 32 бита;потому что вам уже нужно это количество бит для хранения фактических чисел;но вам также необходимо знать длину в битах закодированных чисел;для этого вам понадобится дополнительное хранилище.Все это действительно при условии, что эти числа не каким-то образом избыточны и могут быть сжаты.

Конечно, есть способы сделать его короче 4 байтов на целое число;в зависимости от точных свойств чисел, с которыми нужно работать, лучше подойдет тот или иной алгоритм;Вот краткий список нескольких возможных алгоритмов:

  • Если вы знаете, что целые числа могут быть длиной до 9 битов, вы можете использовать простой метод, показанный выше, но со смещениями от 9 дохранить номера;с помощью этого метода вы получите до 45 битов для 5 значений.
  • Наличие индикатора длины перед каждым элементом - это еще одна возможность (как предлагает Роберт Рухани )
  • ДругойНапример, предлагается в этот вопрос (с использованием Dlugosz 'Variable-Length-Integer )
  • Вы также можете использовать Количество переменной длины .

Первые два метода имеют тот недостаток, что они могут представлять только фиксированное максимальное количество битов.Этот вид обработки относится к области сжатия , для более теоретического анализа обязательно ознакомьтесь с литературой по этой теме;особый интерес здесь представляют универсальные коды , как указано в комментарии Каганара;последние два алгоритма в списке выше являются такими универсальными кодами.Они должны привести вас к 48 битам для вашего примера ввода 5 значений с 5,5,6,7 и 9 битами (4 раза по 8 бит для 4 значений, имеющих менее 8 бит, и 1 раз по 16 бит для 9 битчисло).Преимущество этих двух методов перед другими методами в списке состоит в том, что они подходят для произвольно больших чисел;могут быть и другие универсальные коды, лучше подходящие для ваших целей, обязательно проверьте и другие.

0 голосов
/ 30 декабря 2011

Я думаю, что сжатие 5, 5, 6, 7, 9 в 32 бита невозможно.Слишком маленькое хранилище, чтобы вместить всю информацию.

Прежде всего, мы можем минимизировать биты заполнения, наблюдая максимально возможные биты элемента.Если мы используем 32-битную переменную для максимум 10-битных элементов, мы тратим 22 бита.Мы можем избавиться от 22 битов на каждый элемент с 10-битным типом данных.

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

0 голосов
/ 30 декабря 2011

Вы можете включить 4-6 бит перед каждым элементом, который содержит размер в битах элемента, в зависимости от максимального размера элемента (4, если максимальный размер <16, 5, если максимальный размер <32, 6, если макс.size <64). </p>

Декодирование будет таким простым:

  • читать 4 бита, чтобы определить размер элемента
  • читать x бит как элемент (где x эторазмер элемента)

Из-за изменяемого размера вы не сможете упаковать данные в 32 байта, так как вам необходимо включить какой-либо индикатор размера для каждого элемента.В этом случае, если вы используете размер 4 бита, вы будете использовать 52 бита, что составляет всего 32,5% от исходного размера в 160 бит.

...