Bitshift

Материал из MK90.ORG wiki
Перейти к: навигация, поиск

Справка Язык | Библиотеки | Сравнение | Изменения

Побитовый сдвиг влево (<<) и вправо (>>)

Описание

Большинство материалов, приводимых ниже, составлено из великолепного обучающего материала, опубликованного здесь.

В языке C++ существует оператор сдвига влево << и оператор сдвига вправо >>. Эти операторы вызывают сдвиг битов в левом операнде вправо или влево на то количество бит, которое указано в правом операнде.

Синтаксис


переменная << число_бит
переменная >> число_бит

Параметры

переменная - (типа byte, int, long)

число_бит - целое значение <= 32

Пример


    int a = 5;        // в двоичном виде: 0000000000000101
    int b = a << 3;   // в двоичном виде: 0000000000101000, или 40 в десятичном
    int c = b >> 3;   // в двоичном виде: 0000000000000101, или снова 5, с которого мы начали

Когда происходит сдвиг значения x на y бит влево (x << y), у бит слева у значения x теряется:


    int a = 5;        // в двоичном виде: 0000000000000101
    int b = a << 14;  // в двоичном виде: 0100000000000000 - первая единица в 101 теряется

Существует прием быстрого получения константы "два в степени X", основанный на том, что позиционный сдвиг единицы позволяет это сделать довольно наглядно:

   1 <<  0  ==    1
   1 <<  1  ==    2
   1 <<  2  ==    4
   1 <<  3  ==    8
   ...
   1 <<  8  ==  256
   1 <<  9  ==  512
   1 << 10  == 1024
   ...

Когда вы сдвигаете x вправо на y бит (x >> y), и старший бит x равен 1, результат будет зависеть от типа переменной x. Если x - знаковый тип (например, Int), старший бит по совместительству является знаковым (1 соответствует отрицательному числу, 0 - положительному) и, в этом случае, знаковый бит копируется в старший бит при каждом сдвиге (скорее, по эзотерическо-историческим причинам):


    int x = -16;     // в двоичном виде: 1111111111110000
    int y = x >> 3;  // в двоичном виде: 1111111111111110

Это поведение называется "расширение знаком" и довольно часто делает вовсе не то, что требуется. Если надо всегда копировать в самый левый бит ноль, явно приведите сдвигаемое выражение к беззнаковому типу:


    int x = -16;                   // в двоичном виде: 1111111111110000
    int y = (unsigned int)x >> 3;  // в двоичном виде: 0001111111111110

Если быть внимательным с эффектом расширения знаком, оператор сдвига вправо можно использовать для деления на степень двойки:


    int x = 1000;
    int y = x >> 3;   // целочисленное деление 1000 на 8, получается y = 125.

Руководство по Wiring


Исправления, пожелания и новые статьи должны быть опубликованы через Форум.

Оригинальные тексты руководств и переводы распространяются Arduino и MK90 на условиях лицензии Creative Commons Attribution-ShareAlike 3.0 License. Примеры исходных кодов и ссылки являются общественным достоянием.