Вам приходилось использовать смещение битов в реальных проектах программирования? Большинство (если не все) языков высокого уровня имеют в них операторы сдвига, но когда вы действительно должны их использовать?
Вам когда-нибудь приходилось использовать бит-сдвиг в реальных проектах?
Ответ 1
Я все еще пишу код для систем, не поддерживающих поддержку с плавающей запятой в оборудовании. В этих системах вам нужно битовое смещение почти для всех ваших арифметических действий.
Также вам нужны сдвиги для генерации хэшей. Полиномиальная арифметика (CRC, коды Рида-Соломона являются основными приложениями) или использует сдвиги также.
Однако сдвиги используются только потому, что они удобны и выражают именно то, что писатель намеревался. Вы можете эмулировать все бит-сдвиги с умножением, если хотите, но это будет сложнее писать, менее читабельным и иногда более медленным.
Компиляторы обнаруживают случаи, когда умножение можно свести к сдвигу.
Ответ 2
Да, я использовал их много раз. Бит-скручивание важно для встроенных аппаратных средств, где бит-маски очень распространены. Это также важно при программировании игр, когда вам нужен последний бит производительности.
Изменить: Также я использую их для управления растровыми изображениями, например, с помощью изменения глубины цвета или преобразования RGB ↔ BGR.
Ответ 3
- Создание хороших значений флага для перечислений (вместо ввода вручную 1, 2, 4...)
- Распаковка данных из бит-полей (многие сетевые протоколы используют их)
- Обход Z-кривой
- Производительность hacks
И я не могу придумать много случаев, когда они используются. Обычно это происходит наоборот - возникает определенная проблема, и оказывается, что использование битовых операций даст наилучшие результаты (обычно с точки зрения производительности - времени и/или пространства).
Ответ 4
Одно место, которое я использую все это время, - это перенос энтианности целых чисел для кросс-платформенных приложений. Они также иногда пригождаются (наряду с другими операциями манипуляции бит) при смешении 2D-графики.
Ответ 5
Я использовал их несколько раз, но почти всегда для разбора формата двоичного файла.
Ответ 6
Разумная статья здесь: http://greatjustice.info/the-lost-art-of-bitmasks/
Ответ 7
Сдвиги бит бывают быстрыми. Они были реализованы в наборах инструкций процессора задолго до операций деления и модуля. Многие из нас использовали битовые сдвиги для арифметики, которые просты на карандаше и бумаге, но недоступны на наших процессорах.
Например:
- Я использовал бит-сдвиги для проектов с участием факторинга больших композитов в их основные факторы.
- Я также использовал бит-сдвиги для нахождение квадратного и кубического корней произвольно большие целые числа.
Ответ 8
Да, все еще нужно.
Здесь, например, в моей работе мы разрабатываем программное обеспечение для связи с ПЛК через последовательный порт 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);
С уважением.
Ответ 9
Когда я писал на ассемблере, мой код был полон бит-сдвига и маскировки.
Было ли это также справедливым количеством в C.
Не так много сделал на JavaScript или на языках сервера.
Наверное, лучшим современным использованием является переполнение массива булевых значений, представленных как единицы и нули. Я всегда оставил смену и проверял бит знака в сборке, но на языках более высокого уровня вы сравниваете значение со значением.
Например, если у вас есть 8 бит, вы проверяете верхний бит с "if (a > 127) {...}". Затем вы оставите смену (или умножьте на 2), выполните "и" с 127 (или выполните вычитание 256, если последний бит был установлен), и сделайте это снова.
Ответ 10
Угу. Я должен написать алгоритмы шифрования раньше и это определенно использует их.
Они также полезны при использовании целых чисел и т.д. для отслеживания статусов.
Ответ 11
Я использовал их много в сжатии/распаковке изображений, где биты в растровом файле были сжаты. Используя http://en.wikipedia.org/wiki/Huffman_coding вещи, которые сжимаются, состоят из разного количества бит (они не все байт-выровнены), и поэтому вам нужно бит-сдвиг их при их кодировании или декодировании.
Ответ 12
Например, в реализации криптографических методов на таких языках, как C, С++. Двоичные файлы, алгоритмы сжатия и операции с логическими списками - побитовая операция всегда хороша =)
Ответ 13
Переключение битов не решает проблемы программирования на высоком уровне, но нам иногда приходится решать проблемы нижнего уровня, и для этого удобно не писать отдельную библиотеку в C, чтобы сделать это. То, что, когда он привыкает, больше всего - моя догадка.
Я лично использовал его в написании кодировщика для конвертера символов EBCDIC.
Ответ 14
Да, у меня есть. Как вы, вероятно, подозреваете, что он, скорее всего, будет найден в низкоуровневом программировании, например, при разработке драйверов устройств. Но я работал над проектом С#, где мне приходилось разрабатывать веб-службу, которая получала данные от медицинских устройств. Все двоичные данные, хранящиеся в устройстве, были закодированы в пакеты SOAP, но двоичные данные были сжаты и закодированы. Поэтому, чтобы разогнать его, вам придется делать много и много бит-манипуляций. И, кроме того, вам придется делать много бит смещения для анализа любой полезной информации, например, серийный номер устройства - это нижняя половина второго байта или что-то в этом роде. Также я видел, как некоторые люди в мире .NET(С#) используют маскирование бит и атрибут флага, у меня лично никогда не было желания это делать.
Ответ 15
При преобразовании чисел от небольшого числа endian в формат большого конца и наоборот
Ответ 16
Я работаю для производителя периферийных устройств. Я столкнулся и должен был реализовать код, который использует бит-сдвиги, почти каждый день.
Ответ 17
Быстрое преобразование Фурье - FFT, и техника Cooley-Tukey потребует использования операций смещения бит.
Ответ 18
Найдите ближайшую силу двух больших или равных заданному числу:
1 << (int)(ceil(log2(given)))
Необходим для текстурирования на оборудовании, которое не поддерживает произвольные размеры текстур.
Ответ 19
Бит-сдвиг используется в расшифровке протоколов онлайн-игр. Протоколы предназначены для использования как можно большей полосы пропускания, поэтому вместо того, чтобы передавать количество игроков на сервере, имена и т.д. В 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;
}
}
Конечно, рассматриваете ли вы это как настоящий проект или просто хобби (на С#) зависит от вас.
Ответ 20
Да, они использовались в парсере транспортного потока MPEG2-2. Это было легче и было лучше читаемо.
Ответ 21
Мне пришлось написать программу для анализа файлов .ifo на DVD-дисках. Это те, которые объясняют, сколько названий, глав, меню и т.д. Находятся на диске. Они состоят из упакованных битов всех размеров и выравниваний. Я подозреваю, что многие бинарные форматы требуют аналогичного смещения битов.
Ответ 22
Я видел побитовые операторы, используемые, когда в качестве параметра свойства использовались несколько флагов. Например, номер 4 = 1 0 0 означает, что установлен один из трех флагов. Это не хорошо для публичного API, но оно может ускорить работу в особых случаях, так как проверка бит выполняется быстро.
Ответ 23
Каждый битберт-er, который я когда-либо писал, не мог быть завершен без возможности скольжения бит слева и справа.
Ответ 24
Я использовал их в играх для упаковки кучи флагов в один байт / char для сохранения на карту данных. Такие вещи, как сохранение статуса разблокируемых и т.д. В настоящее время это не так много, но может сохранить работу.
Ответ 25
Я использую его в проекте для встроенной системы, которая должна читать данные EDID монитора. Некоторые данные в EDID закодированы следующим образом:
Байт # 3:
Горизонтальная заливка - более низкие 8 бит
Байт # 4:
Lower Nibble: Горизонтальная заливка - верхние 4 бита
Верхний кусочек: что-то еще
Ответ 26
Да, при выполнении двоичной связи между приложениями Java и С# одно - это байтовое упорядочение по бай-ину, а другое - мало-endian (не обязательно в этом порядке). Я создал класс InputStream, который мог читать числа с другим порядком байтов, и для работы использовался байтовый сдвиг.
Иногда также, когда вы хотите поместить 4 шорта в 4 байта длинной, это будет случай использования смещения байта. Я думаю, что сделал это много лет назад...
Ответ 27
Еще одна очень распространенная вещь - сделать 4-битный сдвиг при извлечении высокого nibble байта, то есть
#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte) ( (byte) & 0x0F)
Ответ 28
Бит сдвига также требуется при общении с "нижним уровнем", электронными цифровыми Ethernet-IO-боксами или ПЛК, которые обычно упаковывают нечетные значения ввода/вывода в байты.
Ответ 29
Да, смещение битов используется на низкоуровневом встроенном программном обеспечении все время. Его также можно использовать в качестве почти магического трюка для выполнения чрезвычайно быстрых математических операций, посмотрите
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
Ответ 30
Да, все время. Как и эти макросы для упаковки и распаковки координаты 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))