Когда подходят побитовые операции

Я знаю основную предпосылку того, что такое побитовая операция (хотя был бы признателен за объяснение "для чайников"); однако я не знаю, когда целесообразно использовать эту технику.

насколько я понимаю, это старые архитектуры ЦП могут выполнять побитовые операции быстрее, чем другие операции и, следовательно, было выгодно знать, как их использовать. Учитывая, что это уже не так; по-прежнему ли целесообразно их выполнять, и если да, то для чего целью и при каких условиях? (Меня особенно интересует контекст C#, но я рад получить общие ответы)

5 ответов


побитовые операции-это отличный способ быстро проверить флаг, который может быть установлен на переменную.

следующий пример подчеркивает преимущества использования побитовых операций на Flag перечисления, а также хранения поле bitstuffed в базу данных. Затем поле bitstuffed можно легко проверить, содержит ли оно одно значение или подмножество значений из Flag перечисление.

пример:

A


проблема не в том, что побитовые операции быстрее, чем целочисленные операции (хотя обычно это так), а в том, что они разные операции разные целей.

концептуально байты и шорты и Инты действительно крошечные массивы биты и битовые операторы операторы булевский массив. В C# в настоящее время побитовые операторы в основном используются для [Flags] перечисления и в расчетах за GetHashCode но есть бесконечные способы использования массивов битов.


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

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


они могут быть действительно полезны во встроенных ситуациях управления, когда пространство находится в премиум-классе. Например, один байт данных может представлять 8 бит ввода-вывода, а маски могут использоваться для извлечения интересующих бит из порта ввода-вывода (например, if PIN0 = 1, PIN1 = 2, PIN2 = 4, PIN3 = 8 и так далее, тут:

  • чтобы получить значение PIN0, мы можем сказать PORT0 & PIN0 == 0.
  • установить PIN1 к 1, мы можем cay PORT0 |= PIN1.
  • установить PIN2 к 0, мы можем сказать PORT0 &= ~PIN2.

отсюда из встроенного контроля я редко вижу, что это используется в эти дни. В мире c# гораздо чаще можно увидеть отдельные логические поля для каждого интересующего значения, поскольку накладные расходы на самом деле не имеют большого значения с современным оборудованием (хотя вы можете столкнуться с одним или двумя случаями, когда побитовые операции используются для хранения многих таких флагов в одной переменной).

существует также Интересное приложение в графике. Аккуратный трюк для курсоров или ограничивающих коробок-добавить их XOR'ING форма курсора с изображением ниже. Выполнение той же операции снова приведет к исходному изображению.


один из способов, которым я время от времени использую побитовые операторы, - генерировать подмножества данной строки/массива с помощью двоичной маски, это выглядит так: (извините, код c++)

string s = "abcde";
for(int i = 0; i < 1<<s.size(); i++) {
  string tmp;
  for(int j = 0; j < s.size(); j++) if(i & 1<<j) tmp.push_back(s[j]);
  cout<<tmp<<endl; 
}

вы можете проверить этот проницательный конкурс-ориентированный учебник по программированию:немного веселья: весело с битами