Побитовые операции
- Битовые операции в PHP на примерах - пример на правах пользователей
- http://ru.wikipedia.org/wiki/%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8
- http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BB%D0%BE%D0%B3%D0%B8%D0%BA%D0%B0
- http://ru.wikipedia.org/wiki/%D0%90%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BB%D0%BE%D0%B3%D0%B8%D0%BA%D0%B0#.D0.97.D0.B0.D0.BA.D0.BE.D0.BD.D1.8B_.D0.B2.D0.B5.D0.BD.D1.8A.D1.8E.D0.BD.D0.BA.D1.86.D0.B8.D0.B8
Таблица
Оператор | Название | Пример Бин. | Результат Бин. | Описание |
---|---|---|---|---|
& | Побитовая операция "И" | 2&3 0010&0011 | 2 0010 | Возвращает 1 в позиции каждого бита, где соответствующий бит обоих операндов равен 1 |
| | Побитовая операция "ИЛИ" | 2|3 0010|0011 | 3 0011 | Возвращает 1 в позиции каждого бита, где соответствующий бит одного или обоих операндов равен 1 |
~ | Побитовая операция "НЕ" | ~3 ~0011 | 12 1100 | Инвертирует биты операнда. |
^ | Побитовая операция "ИСКЛЮЧАЮЩЕЕ ИЛИ" | 2^3 0010^0011 | 1 0001 | Возвращает 1 в позиции каждого бита, где соответствующий бит одного, но не обоих, операндов равен 1. |
<< | Побитовая операция "сдвиг влево" | 1<<3 0001<<3 | 8 1000 | |
>> | Побитовая операция "сдвиг вправо" | 8>>3 1000>>3 | 1 0001 |
Сдвиг вправо с сохранением знака a >> b Сдвигает операнд a в бинарном представлении на b битов вправо, отбрасывая смещённые биты.
Сдвиг вправо с заполнением нулями a >>> b Сдвигает операнд a в бинарном представлении на b битов вправо, отбрасывая смещённые биты и заполняя слева нулями.
Пример для int x
if (x & 1) // нечетное
if (~x & 1) //четное
х = (х+7) & ~7; // сделаем его ближайшим большим кратным 8
1. сдвиг.
a=b<<5 //переменной а присваивается переменная б, сдвинутая влево на 5
Все биты в переменной сдвигаются на заданое количество позиций влево или вправо, место с противоположной стороны заполняется нулями. например, сдвиг числа на 4 влево:
было: 00101110 стало: 11100000
2. операция И.
a=b&c;
производится над двумя переменными, результат - переменная, в которой каждый бит установлен только если он установлен в обеих исходных переменных.
00101110 11100110 -------- 00100110
3. Операция ИЛИ.
a=b|c;
То же самое что и операция И, только в результате бит выставляется если он выставлен хотя бы в одной исходной переменной.
00101110 11100110 -------- 11101110
4. Операция НЕ.
производится над одной переменной, в С так: a=~b; //АХТУНГ: не путать ~ с символом ! - ето другое НЕ (логическое, а нам надо побитовое).
В результате биты инвертируются - где был 0 станет 1 и наоборот.
5. Исключающее ИЛИ (XOR).
a=b^c;
Похоже на ИЛИ, только в результате бит выставляется, если в исходных переменных биты отличаются, т.е не равны одновременно 0 или 1. Пример:
00101110 11100110 -------- 11001000
Часто используется в той или иной форме для шифрования, прикол в том, что поксорив одно число с другим два раза, получаем исходное число, т.е по сути сначала шифруем, а потом расшифровываем.
6. Установка бита.
Операция установки бита. Дано - переменная один или несколько байт длиной, цель - выставить определенный бит. Это делается наложением битовой маски таким образом:
a=142; // переменная a=a|(1<<5); //выставляем пятый по счету бит.
Как ето работает? просто. рассмотрим по шагам.
- сначала задается переменная a равная 142, в двоичном виде: 10001110.
- затем операцией сдвига (1<<5) мы получаем число 00010000. Вобще это число можно указать в явном виде вместо конструкции (1<<5), но так иногда понятнее.
- после этого производим побитовое ИЛИ над переменной и полученным числом 00010000.
- короче говоря, накладывая маску операцией ИЛИ мы устанавливаем в переменной те биты, которые выставлены в самой маске, а остальные не трогаем.
- соответственно, если нам надо установить несколько бит, то надо накладывать маску с несколькими выставлеными битами, например:
10001110 01011000 -------- 11011110
такую маску можно либо указать в явном виде (как уже говорилось) так и получить объединением все той же операцией ИЛИ:
a=142; // переменная a=a|((1<<5)|(1<<3)|(1<<1)); //выставляем 5, 3 и 1 бит.
7. Очистка бита.
Делается аналогично установке бита, только с операцией И и инвертированной маской. т.е:
a=142; // переменная a=a&(~(1<<2)); //очищаем второй бит.
по сути получается:
10001110 11111101 --------(операция И) 10001100
В результате очищаются те биты, которые равны 0 в маске, а остальные не изменяются.
8. Установка бита dat в массиве байт data
(прием используется в исходнике анализаторе посылок из эфира и пр):
data[10], dat_bit; data[dat_bit/8]|=(1<<(dat_bit%8));
т.е если например надо установить бит 17 - то он установится в третьем байте массива, вторым битом.
9. Перевод числа битов в байты (ну ето просто).
Например, есть у нас переменная bits с числом бит, и надо выяснить сколько ето байт, т.е поделить на 8 с округлением в большую сторону. В результате, например для 17 бит получаем число 3 (три байта т.е).
a=bits/8+((bits%8)?1:0)