В Си есть две операции арифметического битового сдвига: левый сдвиг << и правый сдвиг >>. Эти операции смещают биты в левом операнде влево или вправо на число позиций указанное в правом операнде.
Синтаксис
переменная<<число_бит
переменная>>число_бит
Параметры
переменная - целая переменная тип byte, int или long.
число_бит <= 32.
Пример
int a = 5; // в двоичном виде: 0000000000000101
int b = a << 3; // в двоичном виде: 0000000000101000 или 40 в десятичном
int c = b >> 3; // в двоичном виде: 0000000000000101 возврощаемся назад к 5
Когда вы переносите значение х на у бит (х << у), крайние левые у биты в х теряются, буквально сдвинуты в небытие:
int a = 5; // в двоичном виде: 0000000000000101
int b = a << 14; // в двоичном виде: 0100000000000000 - первая 1 в 101 потеряна
Если вы уверены, что ни один из значимых битов не будет потерян, операцию сдвига влево можно рассматривать как умножение левого операнда на 2. Например, для генерации возведения в степень 2, можно использовать следующие выражения:
1 << 0 == 1
1 << 1 == 2
1 << 2 == 4
1 << 3 == 8
...
1 << 8 == 256
1 << 9 == 512
1 << 10 == 1024
Когда вы сдвигает х вправо на у бит (х >> у), а старший бит в х является 1, поведение операции зависит от конкретного типа данных х. Если х имеет тип Int, то старший бит является знаковым. В этом случае, бит знака (самый старший бит) копируется в нижние биты, это сделано для использования быстрого деления на 2 и для отрицательных чисел:
int x = -16; // в двоичном виде: 1111111111110000
int y = x >> 3; // в двоичном виде: 1111111111111110
Такое поведение, называется знаковым расширением. Но обычно мы хотим иного поведения: вместо этого, часто нужно, чтобы сдвигались слева нули. Получается, что правила правого сдвига различны для типа int и типа unsigned Int, поэтому можно использовать приведение типа, чтобы подавить копирование единиц слева:
int x = -16; // в двоичном виде: 1111111111110000
int y = (unsigned int)x >> 3; // в двоичном виде: 0001111111111110
Если вы внимательны, чтобы избежать знакового расширения, вы можете использовать оператор сдвига вправо >> как способ разделить на степени 2. Например:
int x = 1000;
int y = x >> 3; // целочисленное деление 1000 на 8, получим y = 125.
Справочник
Материалы взяты с официального сайта проекта Arduino и представлены по лицензии Creative Commons Attribution-ShareAlike 3.0 License.
Источник: http://arduino.cc/en/Reference/Bitshift |