Побитовые операции помогут мне сериализовать некоторые bool? - PullRequest
3 голосов
/ 01 февраля 2011

Я не привык к бинарным файлам, и я пытаюсь освоить его.Мне удалось сохранить некоторые целые и неподписанные символы и читать их без особой боли.Теперь, когда я пытаюсь сохранить некоторые логические значения, я вижу, что каждый из моих bool занимает ровно 1 октет в моем файле, что кажется логичным, так как одиночный bool хранится в данных размера char (поправьте меня, если я ошибаюсь)!).

Но так как для сериализации у меня будет 3 или 4 bools, я считаю, что хранить их напрасно - это 00000001 00000001 00000000, например, когда у меня может быть 00000110. Я предполагаю получитьэто я должен использовать побитовую операцию, но я не очень хорош с ними ... так может кто-нибудь сказать мне:

  1. Как сохранить до 8 bools в одном октете, используя побитовые манипуляции?
  2. Как дать правильные значения (до 8 bools) из одного октета с помощью побитовой манипуляции?
  3. (И, дополнительный вопрос, может ли кто-нибудь порекомендовать простой, нематематически ориентированныйум, как мой, учебник по манипуляции с битами, если он существует? Все, что я понял, я понял, но не смог применить на практике ...)

Я использую C ++, но, думаю, большинство языков C-syntaxic будут использоватьтакой же вид операции.

Ответы [ 6 ]

2 голосов
/ 01 февраля 2011

Для хранения bools в байте:

bool flag; // value to store
unsigned char b = 0; // all false
int position; // ranges from 0..7
b = b | (flag << position);

Чтобы прочитать это обратно:

flag = (b & (1 << position));
2 голосов
/ 01 февраля 2011

Самый простой способ - использовать std :: bitset, который позволяет использовать индексирование для доступа к отдельным битам (bools), а затем получить полученное значение в виде целого числа.Это также позволяет обратное.

int main() {
  std::bitset<8> s;
  s[1] = s[2] = true;  // 0b_0000_0110
  cout << s.to_ulong() << '\n';
}
1 голос
/ 01 февраля 2011

Сначала основные вещи:

  • Единственная комбинация битов, которая означает ложь, это 00000000, все остальные означают истину, т.е. 00001000,01010101
  • 00000000 = 0 (десятичное число), 00000001 = 2 ^ 0, 00000010 = 2 ^ 1, 00000100 = 2 ^ 2,…. , 10000000 = 2 ^ 7
  • Существует большая разница между операндами (&&, ||) и (&, |), первые из которых дают результат логической операции между двумя числами, например:

    00000000 && 00000000 = false,

    01010101 && 10101010 = true

    00001100 || 00000000 = правда,

    00000000 || 00000000 = ложь

    Вторая пара выполняет побитовую операцию (логическую операцию между каждым битом чисел):

    00000000 & 00000000 = 00000000 = false

    00001111 и 11110000 = 00000000 = false

    01010101 и 10101001 = 00000001 = true

    00001111 | 11110000 = 11111111 = true

    00001100 | 00000011 = 00001111 = true


Чтобы работать с этим и играть с битами, вам нужно знать только некоторые основные приемы:

  • Чтобы установить бит в 1, вы выполняете операцию | с октетом, который имеет 1 в этом положении и ceros в остальных.

Например: мы хотим, чтобы первый бит октета A был равен 1, который мы делаем: A | 00000001

  • Чтобы установить бит в 0, вы выполняете операцию с октетом, который имеет 0 в этой позиции и единицы в остальных.

Например: мы хотим, чтобы последний бит октета A был 0, который мы делаем: A & 01111111

  • Чтобы получить логическое значение, которое содержит бит, вы выполняете операцию с октетом, который имеет 1 в этой позиции и ceros в остальных.

Например: мы хотим видеть значение третьего бита октета A, мы делаем: A & 00000100, если A было XXXXX1XX, мы получаем 00000100 = true, а если A было XXXXX0XX, мы получаем 00000000 = ложь;

1 голос
/ 01 февраля 2011

Попробуйте прочитать это по порядку.

  1. http://www.cprogramming.com/tutorial/bitwise_operators.html

  2. http://www -graphics.stanford.edu / ~ seander / bithacks.html # ConditionalSetOrClearBitsWithoutBranching

Некоторые люди подумают, что 2-я ссылка слишком жесткая, но как только вы освоите простую манипуляцию, она пригодится.

1 голос
/ 01 февраля 2011

Без упаковки в шаблонном / препроцессорном оборудовании:

  • Установить бит 3 в var :
    var |= (1 << 3)
  • Установить бит n in var :
    var |= (1 << n)
  • Сбросить бит n in var :
    var &= ~(1 << n)
  • Тестовый бит n in var : (!! гарантирует, что результат равен 0 или 1)
    !!(var & (1 << n))
0 голосов
/ 01 февраля 2011

Вы всегда можете сериализовать битовые поля.Что-то вроде:

struct bools 
{
    bool a:1;
    bool b:1;
    bool c:1;
    bool d:1;
};

имеет размер 1

...