Чтение / запись сжатых двоичных данных - PullRequest
1 голос
/ 07 декабря 2009

Я читаю везде, где люди говорят о сжатии объектов по частям. Такие вещи, как «Первые три бита представляют то-то и то-то, затем следующие два бита представляют это и двенадцать битов для этого» * ​​1001 *

Я понимаю, почему было бы желательно минимизировать использование памяти, но я не могу придумать хороший способ реализовать это. Я знаю, что упаковал бы его в одно или несколько целых чисел (или длинных, что угодно), но я не могу представить себе простой способ работы с ним. Было бы неплохо, если бы существовал класс, в котором я мог бы получить / установить произвольные биты из двоичного поля произвольной длины, и он позаботился бы обо мне, и мне не пришлось бы копаться с & 's и |' с и маски и тому подобное.

Существует ли стандартная модель для такого рода вещей?

Ответы [ 4 ]

3 голосов
/ 07 декабря 2009

С MSDN :

Класс BitArray

Управляет компактным массивом значений битов, которые представлены как логические значения, где true указывает, что бит включен (1), а false указывает, что бит выключен (0).

Пример:

BitArray myBitArray = new BitArray(5);
myBitArray[3] = true; // set bit at offset 3 to 1

BitArray позволяет вам устанавливать только отдельные биты. Если вы хотите закодировать значения с большим количеством битов, вероятно, нет смысла копаться в & & s и |, а также в масках и прочем: -)

1 голос
/ 07 декабря 2009

Возможно, вы захотите проверить структуру BitVector32 в .NET Framework. Он позволяет вам определять «секции», которые представляют собой диапазоны битов внутри int, а затем читать и записывать значения в эти секции.

Основным ограничением является то, что оно ограничено одним 32-разрядным целым числом; это может или не может быть проблемой в зависимости от того, что вы пытаетесь сделать. Как упоминалось в dtb, BitArray может обрабатывать битовые поля любого размера, но вы можете получать и устанавливать только один бит за раз - нет поддержки разделов, как в BitVector32.

0 голосов
/ 07 декабря 2009

Вместо того, чтобы использовать инструментарий или классы-обертки для конкретных платформ, я думаю, вам лучше прикусить пулю и изучить свои & s и | s и 0x04s и то, как работают все побитовые операторы. В общем, именно так это и делается для большинства проектов, а операции выполняются очень быстро. Операции практически идентичны на большинстве языков, поэтому вы не будете зависеть от определенного инструментария.

0 голосов
/ 07 декабря 2009

То, что вы ищете, называется побитовой операцией.

Например, допустим, мы собираемся представить значение RGB в младших 24 битах целого числа, где R - это биты 23-16, G - это биты 15-8, а B - это биты 7-0.

Вы можете установить R на любое значение от 0 до 255, не влияя на другие биты, подобные этому:

void setR(ref int RGBValue, int newR)
{
  int newRValue = newR << 16; // shift it left 16 bits so that the 8 low-bits are now in position 23-16
  RGBValue = RGBValue & 0x00FF; // AND it with 0x00FF so that the top 16 bits are set to zero
  RGBValue = RGBValue | newRValue;   // now OR it with the newR value so that the new value is set.
}

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

...