Использование побитовых операций

Как уже говорилось, побитовые операции используются для обработки отдельных двоичных разрядов памяти. Для манипулирования отдельным битом необходимо научиться делать следующее:

· определять значение заданного бита;

· устанавливать значение заданного бита в значение 0 или 1;

· инвертировать значение заданного бита.

Это можно сделать так:

unsigneda = 1234; // Целое значение, битами которого мы будем управлять

unsignedshortn = 4;// Номер необходимого бита (от 0 до 31)

boolr; // Значение результата (0 или 1)

/* Узнаем, чему равен n-й бит (двоичный разряд) значения a. Результат поместим в переменную r */

r = a& (1U<<n);

cout<< "Разряд с номером " <<n<< " равен " <<r<<endl; //значение1

/* Установим n-й бит (двоичный разряд) значения aв0. Результат поместим в переменную а */

a = a& (~ (1U<<n));

cout<< "Значение а равно " <<a<<endl; //значение1218

/* Проверяем */

r = a& (1U<<n);

cout<< "Разряд с номером " <<n<< " равен " <<r<<endl; //значение0

/* Возвращаем n-й бит (двоичный разряд) значения a в 1. Результат поместим в переменную а*/

a = a | (1U<<n);

cout<< "Значение а равно " <<a<<endl; //значение1234

/* Проверяем */

r = a& (1U<<n);

cout<< "Разряд с номером " <<n<< " равен " <<r<<endl; //значение1

/* Инвертируем n-й бит (двоичный разряд) значения a. Результат поместим в переменную а */

a = a ^ (1U<<n);

cout<< "Значение а равно " <<a<<endl; //значение1218

/* Проверяем */

r = a& (1U<<n);

cout<< "Разряд с номером " <<n<< " равен " <<r<<endl; //значение0

/* Еще раз инвертируем n-й бит (двоичный разряд) значения a. Результат поместим в переменную а */

a = a ^ (1U<<n);

cout<< "Значение а равно " <<a<<endl; //значение1234

/* Проверяем */

r = a& (1U<<n);

cout<< "Разряд с номером " <<n<< " равен " <<r<<endl; //значение1

Изменяя значение переменной nв диапазоне от 0 до 31 можно выполнить все эти действия над любым битом переменной aкакое бы значение она не содержала.

Таким образом, для того, чтобы узнать, чему равен двоичный разряд с номером nв значении переменной a, мы воспользовались выражением a& (1U<<n).

Иллюстрация вычисления этого выражения:

Номер разряда: 31 30 … 11 10 9 8 7 6 5 4 3 2 1 0

Использование побитовых операций - student2.ru 1U: 0 0 … 0 0 0 0 0 0 0 0 0 0 0 1 = 1

1U<<n: 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0

Значение a: 0 0 … 0 1 0 0 1 1 0 1 0 0 1 0 = 1234

a& (1U<<n): 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0 = 16

Результатом вычисления этого выражения является целое значение не равное 0. Операция присваивания этого значения логической переменной r автоматически преобразует целое значение 16 в логическое значение true (т.е. 1).

Если бы значение a имело бы разряд с номером 4 равным 0, то результатом вычисления этого выражения было бы значение 0. При выполнении операции присваивания это значение было бы преобразовано в логическое значение false (т.е. 0).

Для установки значения разряда с номером n в переменной aв значение 0 используется выражение a& (~ (1U<<n)).

Иллюстрация вычисления этого выражения:

Номер разряда: 31 30 … 11 10 9 8 7 6 5 4 3 2 1 0

Использование побитовых операций - student2.ru 1U: 0 0 … 0 0 0 0 0 0 0 0 0 0 0 1 = 1

1U<<n: 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0

~ (1U << n): 1 1 … 1 1 1 1 1 1 1 0 1 1 1 1

Значение a: 0 0 … 0 1 0 0 1 1 0 1 0 0 1 0 = 1234

a& (1U<<n): 0 0 … 0 1 0 0 1 1 0 0 0 0 1 0 = 1218

Для установки значения разряда с номером n в переменной aв значение 1 используется выражение a|(1U<<n).

Иллюстрация вычисления этого выражения:

Номер разряда: 31 30 … 11 10 9 8 7 6 5 4 3 2 1 0

Использование побитовых операций - student2.ru 1U: 0 0 … 0 0 0 0 0 0 0 0 0 0 0 1 = 1

1U<<n: 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0

Значение a: 0 0 … 0 1 0 0 1 1 0 0 0 0 1 0 = 1218

a | (1U<<n): 0 0 … 0 1 0 0 1 1 0 1 0 0 1 0 = 1234

Для инвертирования значения разряда с номером n в переменной aиспользуется выражение a^(1U<<n).

Иллюстрация вычисления этого выражения при a = 1218:

Номер разряда: 31 30 … 11 10 9 8 7 6 5 4 3 2 1 0

Использование побитовых операций - student2.ru 1U: 0 0 … 0 0 0 0 0 0 0 0 0 0 0 1 = 1

1U<<n: 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0

Значение a: 0 0 … 0 1 0 0 1 1 0 0 0 0 1 0 = 1218

a ^ (1U << n): 0 0 … 0 1 0 0 1 1 0 1 0 0 1 0 = 1234

Но, если a = 1234, то:

Номер разряда: 31 30 … 11 10 9 8 7 6 5 4 3 2 1 0

Использование побитовых операций - student2.ru 1U: 0 0 … 0 0 0 0 0 0 0 0 0 0 0 1 = 1

1U<<n: 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0

Значение a: 0 0 … 0 1 0 0 1 1 0 1 0 0 1 0 = 1234

a ^ (1U<<n): 0 0 … 0 1 0 0 1 1 0 0 0 0 1 0 = 1218

Примеры применения побитовых операций.

Примеры:

unsigned a = 20, n = 3, r;

r = a << n;

cout<<r<<endl; //На экран выведено 160

r = a >> n;

cout<<r<<endl; //На экран выведено 2

Иллюстрация:

Номер разряда: 31 30 … 8 7 6 5 4 3 2 1 0

Значение a: 0 0 … 0 0 0 0 1 0 1 0 0 = 20

Операция: a<<n

Значение r: 0 0 … 0 1 0 1 0 0 0 0 0 = 160

Операция: a>>n

Значение r: 0 0 … 0 0 0 0 0 0 0 1 0 = 2

inta = 14, b = 7, r;

r = a&b;

cout<<r<<endl; //На экран выведено6

r = a | b;

cout<<r<<endl; //На экран выведено15

r = a ^ b;

cout<<r<<endl; //На экран выведено9

Иллюстрация:

Номер разряда: 31 30 … 8 7 6 5 4 3 2 1 0

Значение a: 0 0 … 0 0 0 0 0 1 1 1 0 = 14

Значение b: 0 0 … 0 0 0 0 0 0 1 1 1 = 7

Операция: a&b

Значение r: 0 0 … 0 0 0 0 0 0 1 1 0 = 6

Операция: a | b

Значение r: 0 0 … 0 0 0 0 0 1 1 1 1 = 15

Операция: a ^ b

Значение r: 0 0 … 0 0 0 0 0 1 0 0 1 = 9

unsigneda = 1234; // Целое значение, битами которого мы будем управлять

unsignedshortn = 4;// Номер необходимого бита (от 0 до 31)

boolr; // Значение результата (0 или 1)

/* Узнаем, чему равен n-й бит (двоичный разряд) значения a. Результат поместим в переменную r */

r = a& (1U<<n);

cout<< "Разряд с номером " <<n<< " равен " <<r<<endl; //значение1

Иллюстрация вычисления этого выражения:

Номер разряда: 31 30 … 11 10 9 8 7 6 5 4 3 2 1 0

Использование побитовых операций - student2.ru 1U: 0 0 … 0 0 0 0 0 0 0 0 0 0 0 1 = 1

1U<<n: 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0

Значение a: 0 0 … 0 1 0 0 1 1 0 1 0 0 1 0 = 1234

a& (1U<<n): 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0 = 16

Наши рекомендации