Если распределение битов между этими числами известно заранее, это просто: просто поместите биты каждого элемента в массиве в правильную позицию в результирующем 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 битчисло).Преимущество этих двух методов перед другими методами в списке состоит в том, что они подходят для произвольно больших чисел;могут быть и другие универсальные коды, лучше подходящие для ваших целей, обязательно проверьте и другие.