Побитовые операции: различия между версиями

Материал из support.qbpro.ru
imported>Supportadmin
(Новая страница: «*[http://habrahabr.ru/post/134557/ Битовые операции в PHP на примерах] - пример на правах пользователей *http…»)
 
imported>Supportadmin
Нет описания правки
 
Строка 1: Строка 1:
*[http://learn.javascript.ru/bitwise-operators Примеры. Побитовые операторы js]
*[http://habrahabr.ru/post/134557/ Битовые операции в PHP на примерах] - пример на правах пользователей
*[http://habrahabr.ru/post/134557/ Битовые операции в 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%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

Текущая версия от 18:32, 5 августа 2013


Таблица

Оператор Название Пример Бин. Результат Бин. Описание
& Побитовая операция "И" 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); //выставляем пятый по счету бит.

Как ето работает? просто. рассмотрим по шагам.

  1. сначала задается переменная a равная 142, в двоичном виде: 10001110.
  2. затем операцией сдвига (1<<5) мы получаем число 00010000. Вобще это число можно указать в явном виде вместо конструкции (1<<5), но так иногда понятнее.
  3. после этого производим побитовое ИЛИ над переменной и полученным числом 00010000.
  4. короче говоря, накладывая маску операцией ИЛИ мы устанавливаем в переменной те биты, которые выставлены в самой маске, а остальные не трогаем.
  5. соответственно, если нам надо установить несколько бит, то надо накладывать маску с несколькими выставлеными битами, например:
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)