Поразрядные операции

Последнее обновление: 09.01.2023

Операции сдвига

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

  • <<

    Сдвигает битовое представление числа, представленного первым операндом, влево на определенное количество разрядов, которое задается вторым операндом.

  • >>

    Сдвигает битовое представление числа вправо на определенное количество разрядов.

Применение операций:

int a = 2 << 2;			// 10  на два разрядов влево = 1000 - 8
int b = 16 >> 3;			// 10000 на три разряда вправо = 10 - 2

Число 2 в двоичном представлении 10. Если сдвинуть число 10 на два разряда влево, то получится 1000, что в десятичной системе равно число 8.

Число 16 в двоичном представлении 10000. Если сдвинуть число 10 на три разряда вправо (три последних разряда отбрасываются), то получится 10, что в десятичной системе представляет число 2.

Поразрядные операции

Поразрядные операции также проводятся только над разрядами целочисленных операндов:

  • &: поразрядная конъюнкция (операция И или поразрядное умножение). Возвращает 1, если оба из соответствующих разрядов обоих чисел равны 1

  • |: поразрядная дизъюнкция (операция ИЛИ или поразрядное сложение). Возвращает 1, если хотя бы один из соответствующих разрядов обоих чисел равен 1

  • ^: поразрядное исключающее ИЛИ. Возвращает 1, если только один из соответствующих разрядов обоих чисел равен 1

  • ~: поразрядное отрицание. Инвертирует все разряды операнда. Если разряд равен 1, то он становится равен 0, а если он равен 0, то он получает значение 1.

Применение операций:

int a = 5 | 2;			// 101 | 010 = 111  - 7
int b = 6 & 2;			// 110 & 010 = 10  - 2
int c = 5 ^ 2;			// 101 ^ 010 = 111 - 7

int f = 12;              // 00001100
int d = ~f;			// 11110011   или -13
	
printf("a = %d \n", a);
printf("b = %d \n", b);
printf("c = %d \n", c);
printf("d = %d \n", d);

Например, выражение 5 | 2 равно 7. Число 5 в двоичной записи равно 101, а число 2 - 10 или 010. Сложим соответствующие разряды обоих чисел. При сложении если хотя бы один разряд равен 1, то сумма обоих разрядов равна 1. Поэтому получаем:

101
010
111

В итоге получаем число 111, что в десятичной записи представляет число 7.

Возьмем другое выражение 6 & 2. Число 6 в двоичной записи равно 110, а число 2 - 10 или 010. Умножим соответствующие разряды обоих чисел. Произведение обоих разрядов равно 1, если оба этих разряда равны 1. Иначе произведение равно 0. Поэтому получаем:

110
010
010

Получаем число 010, что в десятичной системе равно 2.

Теперь рассмотрим последний пример - инверсию числа.

Представление отрицательных чисел

Для записи чисел со знаком в Си применяется дополнительный код (two's complement), при котором старший разряд является знаковым. Если его значение равно 0, то число положительное, и его двоичное представление не отличается от представления беззнакового числа. Например, 0000 0001 в десятичной системе 1.

Если старший разряд равен 1, то мы имеем дело с отрицательным числом. Например, 1111 1111 в десятичной системе представляет -1. Соответственно, 1111 0011 представляет -13.

Чтобы получить из положительного числа отрицательное, его нужно инвертировать и прибавить единицу:

int x = 12;
int y = ~x;
y += 1;
printf("y = %d \n", y);   // y=-12
Инверсия и дополнительный код в языке программирования Си
Дополнительные материалы
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850