Побитовые операторы вступают в игру, когда вам нужно работать с байтовыми или битовыми данными.
Здесь я перечисляю несколько примеров использования битовых операций с примерами кода (в произвольном порядке):
1. Они являются общими и частью многих алгоритмов в криптографии и хэш функции (например, MD5).
2. Они также часто используются, если вы хотите «сохранить» пространство, и вы пакет несколько «BOOL» переменные в один int
, например, присвоить бит каждой переменной BOOL. Вы должны использовать побитовые операторы, чтобы иметь возможность индивидуально изменять/читать биты.
Например упаковка 8 бит/Bools в один int
:
flags := 0x00 // All flags are 0
flags |= 0x02 // Turn the 2nd bit to 1 (leaving rest unchanged)
flags |= 0xff // Turn 8 bits (0..7) to 1
flags &= 0xfe // Set the lowest bit to 0 (leaving rest unchanged)
istrue := flags&0x04 != 0 // Test if 3rd bit is 1
3. Другая область сжатия данных, где вы хотите, чтобы получить максимальную отдачу от byte
и использовать все биты в хранить/извлекать некоторую информацию (немного - базовая единица информации в вычислительной и цифровой связи).
4. Аналогично сжатию, но не совсем то же: bitstreams. Он также используется для экономии места в потоке данных, не отправляя полные байты, а скорее поля с произвольной длиной бит.
Я написал и опубликовал высоко оптимизированный пакет Reader и Writer на уровне бит, открытый здесь: github.com/icza/bitio. Вы увидите широкое использование всех видов бит-операций в своих источниках.
5. Другое практическое использование: тестирования определенных свойств (целое число) чисел. Зная двоичное представление целочисленных чисел (Two's complement), в их двоичном представлении есть определенные характеристики чисел. Например целое число (в 2 с дополнением) является даже (можно разделить на 2), если младший бит равен 0:
func isEven(i int) bool {
return i&0x01 == 0
}
Тестируя биты целого числа вы можете сказать, если это сила of 2. Например, если положительное число содержит только один бит 1
, тогда это сила 2 (например,2 = 0x02 = 00000010b
, 16 = 0x10 = 00010000
, но, например, 17 = 0x11 = 00010001
нет мощности 2).
6.Многие процедуры кодирования/декодирования также используют битовые операции. Наиболее тривиальным является UTF-8 encoding, который использует кодировку переменной длины для представления кодовых точек Unicode (rune
в Go) в качестве последовательностей байтов.
Простым вариантом кодирования с переменной длиной слова может быть использование наивысшего бита байта (8-го или 7-го, если индексируется 0), чтобы сигнализировать, требуется ли больше байтов для декодирования числа, а остальные 7 бит всегда являются «полезные» данные. Вы можете проверить старший бит и «отдельные» 7 полезных битов, как это:
b := readOneByte()
usefulBits := b & 0x7f
hasMoreBytes := b & 0x80 != 0
Прибыль использования такого кодирования переменной длины, что даже если вы используете uint64
типа в Go, которая 8 байт памяти , небольшие числа все еще могут быть представлены с использованием меньшего количества байтов (номера в диапазоне 0..127
требуют только 1 байт!). Если образцы, которые вы хотите сохранить или передать, имеют много небольших значений, это само по себе может сжать данные до 1/8-го = 12,5%. Нижняя сторона состоит в том, что большие числа (которые имеют биты даже в самом высоком байте) будут использовать более 8 байтов. Стоит ли это того, что это зависит от эвристики образцов.
X.И этот список можно продолжить ...
Можно ли жить, не зная,/используя битовые операторы Go (и во многих других языках программирования)? Ответ: Да. Но если вы их знаете, иногда они могут сделать вашу жизнь проще и ваши программы более эффективными.
Если вы хотите узнать больше по этой теме, прочитайте статью Википедии: Bitwise operation и google термин «Побитовое руководство по операциям», есть много хороших статей.
Возьмите книгу, подобную «Коду» Петцольда, чтобы получить базовое представление о двоичном представлении и основах вычислений. –