Вам когда-нибудь приходилось использовать бит-сдвиг в реальных проектах?

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

70
06 февр. '09 в 18:10
источник поделиться
43 ответов
  • 1
  • 2

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

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

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

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

46
06 февр. '09 в 18:30
источник

Связанные вопросы


Похожие вопросы

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

Изменить: Также я использую их для управления растровыми изображениями, например, с помощью изменения глубины цвета или преобразования RGB ↔ BGR.

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

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

24
06 февр. '09 в 18:13
источник

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

14
06 февр. '09 в 18:12
источник

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

8
06 февр. '09 в 18:13
источник

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

6
06 февр. '09 в 18:14
источник

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

Например:

  • Я использовал бит-сдвиги для проектов с участием факторинга больших композитов в их основные факторы.
  • Я также использовал бит-сдвиги для нахождение квадратного и кубического корней произвольно большие целые числа.
6
06 февр. '09 в 18:21
источник

Да, все еще нужно.

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

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

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

Byte B;

B := B XOR 4;

Вместо:

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

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

С уважением.

5
06 февр. '09 в 20:07
источник

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

Было ли это также справедливым количеством в C.

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

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

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

4
06 февр. '09 в 21:17
источник

Угу. Я должен написать алгоритмы шифрования раньше и это определенно использует их.

Они также полезны при использовании целых чисел и т.д. для отслеживания статусов.

3
06 февр. '09 в 18:13
источник

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

3
07 февр. '09 в 7:49
источник

Я использовал их много в сжатии/распаковке изображений, где биты в растровом файле были сжаты. Используя http://en.wikipedia.org/wiki/Huffman_coding вещи, которые сжимаются, состоят из разного количества бит (они не все байт-выровнены), и поэтому вам нужно бит-сдвиг их при их кодировании или декодировании.

3
06 февр. '09 в 18:13
источник

Например, в реализации криптографических методов на таких языках, как C, С++. Двоичные файлы, алгоритмы сжатия и операции с логическими списками - побитовая операция всегда хороша =)

3
06 февр. '09 в 18:14
источник

Переключение битов не решает проблемы программирования на высоком уровне, но нам иногда приходится решать проблемы нижнего уровня, и для этого удобно не писать отдельную библиотеку в C, чтобы сделать это. То, что, когда он привыкает, больше всего - моя догадка.

Я лично использовал его в написании кодировщика для конвертера символов EBCDIC.

3
06 февр. '09 в 18:17
источник

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

3
06 февр. '09 в 18:27
источник

При преобразовании чисел от небольшого числа endian в формат большого конца и наоборот

3
06 февр. '09 в 18:41
источник

Быстрое преобразование Фурье - FFT, и техника Cooley-Tukey потребует использования операций смещения бит.

2
06 февр. '09 в 18:16
источник

Найдите ближайшую силу двух больших или равных заданному числу:

1 << (int)(ceil(log2(given)))

Необходим для текстурирования на оборудовании, которое не поддерживает произвольные размеры текстур.

2
08 февр. '09 в 10:46
источник

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

Наиболее яркие примеры этого - в многопользовательских играх Valve, в частности Counter-Strike, Counter-Strike Source. Протокол Quake3 также одинаков, однако Unreal не совсем как slimline.

Вот пример (.NET 1.1)

string data = Encoding.Default.GetString(receive);

if ( data != "" )
{
    // If first byte is 254 then we have multiple packets
    if ( (byte) data[0] == 254 )
    {
        // High order contains count, low order index
        packetCount = ((byte) data[8]) & 15; // indexed from 0
        packetIndex = ((byte) data[8]) >> 4;
        packetCount -= 1;

        packets[packetIndex] = data.Remove(0,9);
    }
    else
    {
        packets[0] = data;

    }
}

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

2
10 апр. '09 в 17:18
источник

Еще одна очень распространенная вещь - сделать 4-битный сдвиг при извлечении высокого nibble байта, то есть

#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte)  ( (byte)       & 0x0F)
1
10 апр. '09 в 18:16
источник

Да, они использовались в парсере транспортного потока MPEG2-2. Это было легче и было лучше читаемо.

1
06 февр. '09 в 18:17
источник

Да, при выполнении двоичной связи между приложениями Java и С# одно - это байтовое упорядочение по бай-ину, а другое - мало-endian (не обязательно в этом порядке). Я создал класс InputStream, который мог читать числа с другим порядком байтов, и для работы использовался байтовый сдвиг.

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

1
06 февр. '09 в 21:06
источник

Каждый битберт-er, который я когда-либо писал, не мог быть завершен без возможности скольжения бит слева и справа.

1
06 февр. '09 в 18:24
источник

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

1
06 февр. '09 в 18:25
источник

Я видел побитовые операторы, используемые, когда в качестве параметра свойства использовались несколько флагов. Например, номер 4 = 1 0 0 означает, что установлен один из трех флагов. Это не хорошо для публичного API, но оно может ускорить работу в особых случаях, так как проверка бит выполняется быстро.

1
06 февр. '09 в 18:22
источник

Я использую его в проекте для встроенной системы, которая должна читать данные EDID монитора. Некоторые данные в EDID закодированы следующим образом:

Байт # 3:
Горизонтальная заливка - более низкие 8 бит
Байт # 4:
Lower Nibble: Горизонтальная заливка - верхние 4 бита
Верхний кусочек: что-то еще
1
06 февр. '09 в 18:30
источник

Мне пришлось написать программу для анализа файлов .ifo на DVD-дисках. Это те, которые объясняют, сколько названий, глав, меню и т.д. Находятся на диске. Они состоят из упакованных битов всех размеров и выравниваний. Я подозреваю, что многие бинарные форматы требуют аналогичного смещения битов.

1
06 февр. '09 в 18:22
источник

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

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

Я использовал побитовые операции один раз, чтобы скомбинировать 1 маленькое целочисленное (2 байта) значение и 2 символа в одном целом. Это спасло мне много памяти по сравнению с проектами моих товарищей.

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

0
21 нояб. '10 в 1:29
источник

Я использовал его для реализации преобразования между UTF-8 и UTF-32.

0
09 июня '10 в 8:29
источник

Да, все время. Как и эти макросы для упаковки и распаковки координаты 3space в/из 32-разрядного целого числа:

#define Top_Code(a, b, c)           ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))                           
#define From_Top_Code(a, b, c, f)   (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))        
0
06 февр. '09 в 23:11
источник
  • 1
  • 2

Посмотрите другие вопросы по меткам или Задайте вопрос