Вам когда-нибудь приходилось использовать сдвиг битов в реальных проектах? - PullRequest
78 голосов
/ 06 февраля 2009

Вам когда-нибудь приходилось использовать битовое смещение в реальных проектах программирования? В большинстве (если не во всех) языках высокого уровня есть операторы сдвига, но когда вам действительно нужно их использовать?

Ответы [ 43 ]

54 голосов
/ 06 февраля 2009

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

Также вам нужны смены для генерации хэшей. Полиномиальная арифметика (CRC, коды Рида-Соломона являются основными приложениями) или использует также сдвиги.

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

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

36 голосов
/ 06 февраля 2009

Да, я использовал их много раз. Битовое переключение важно на встроенном оборудовании, где битовые маски очень распространены. Это также важно в программировании игр, когда вам нужно все до последней части производительности.

Редактировать: Кроме того, я часто использую их для манипулирования растровыми изображениями, например, для изменения глубины цвета или преобразования RGB <-> BGR.

24 голосов
/ 06 февраля 2009
  • Создание хороших значений флага для перечислений (вместо ввода вручную 1, 2, 4 ...)
  • Распаковка данных из битовых полей (многие сетевые протоколы их используют)
  • Обход по Z-кривой
  • Производительность хаков

И я не могу вспомнить многих случаев, когда они используются. Обычно все наоборот - есть определенная проблема, и оказывается, что использование битовых операций даст наилучшие результаты (обычно с точки зрения производительности - времени и / или пространства).

14 голосов
/ 06 февраля 2009

Единственное место, где я использую их все время, - это транспонирование порядковых чисел для кроссплатформенных приложений Они также иногда оказываются полезными (наряду с другими операторами битовых манипуляций) при билинге 2D-графики.

8 голосов
/ 06 февраля 2009

Я использовал их несколько раз, но почти всегда для анализа двоичного формата файла.

6 голосов
/ 06 февраля 2009

Разумная статья здесь: http://greatjustice.info/the-lost-art-of-bitmasks/

6 голосов
/ 06 февраля 2009

Да, все еще это необходимо.

Здесь, в моей работе, например, мы разрабатываем программное обеспечение для связи с ПЛК через последовательный порт COMx. Необходимо обрабатывать биты внутри байта, мы используем сдвиг влево / вправо и логические операторы ИЛИ, XOR и И в день за днем.

Например, предположим, что нам нужно включить бит 3 (справа налево) байта:

Это гораздо эффективнее:

Byte B;

B := B XOR 4;

Вместо:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

Привет.

6 голосов
/ 06 февраля 2009

Битовые сдвиги быстрые. Они были реализованы в наборах команд ЦП задолго до того, как были выполнены операции деления и модуля. Многие из нас использовали сдвиги битов для арифметики, которая проста на бумаге и карандаше, но недоступна для наших процессоров.

Например:

  • Я использовал битовые сдвиги для проектов с участием факторинга больших композитов в их главные факторы.
  • Я также использовал битовые сдвиги для найти квадрат и кубический корень произвольно большие целые числа.
4 голосов
/ 06 февраля 2009

Когда я писал на ассемблере, мой код был полон сдвига битов и маскирования.

Достаточно ли и в С суммы.

Многое не делал на JavaScript или на языках серверов.

Вероятно, лучшее современное использование - это пройти через упакованный массив логических значений, представленных единицами и нулями. Раньше я всегда оставлял сдвиг и проверял бит знака в сборке, но в языках более высокого уровня вы сравниваете значение.

Например, если у вас есть 8 битов, вы проверяете старший бит с помощью «if (a> 127) {...}». Затем вы оставили смещение (или умножили на 2), сделали «и» со 127 (или вычлили 256, если последний бит был установлен) и сделали это снова.

3 голосов
/ 06 февраля 2009

Да, у меня есть. Как вы можете подозревать, это, скорее всего, можно найти в низкоуровневом программировании, например, при разработке драйверов устройств. Но я работал над проектом на C #, где мне нужно было разработать веб-сервис, который бы получал данные от медицинских устройств. Все двоичные данные, хранящиеся на устройстве, были закодированы в пакеты SOAP, но двоичные данные были сжаты и закодированы. Таким образом, чтобы распаковать его, вам придется делать много-много битовых манипуляций. И, кроме того, вам придется много сдвигать бит, чтобы разобрать любую полезную информацию, например, серийный номер устройства - это младшая половина второго байта или что-то в этом роде. Также я видел, как некоторые люди в мире .NET (C #) используют битовую маскировку и атрибут флага, лично у меня никогда не было желания это делать.

...