Сдвиги

Битовые сдвиги в C++ как и в других языках программирования относят к логическим операциям, эти операции обычно выполняются над беззнаковыми целыми числами, позволяя быстро поделить на 2 (сдвиг >>) или умножить на 2 (сдвиг <<). 

Вообще, здесь нужно вспомнить, что любое целое число представляется в двоичной системе счисления

b(a0 + a1*2 + a2*22 + a3*23 +...+ an*2n),

здесь a0, a1, a2,..., an - числа 0 и 1; b - знаковый бит: -1 или 1.

В ячейки памяти ЭВМ 0 и 1 из представления числа записываются в следующем порядке:

b an ... a3 a2 a1 a0

Существуют также беззнаковые типы данных (unsigned)

В этом случае знаковый бит не пишется и порядок записи такой:

an ... a3 a2 a1 a0

Например,

142 = 0*1 + 1*2 + 1*22 + 1*23 + 0*24 + 0*25 + 0*26 + 1*27 = 10001110

Количество битов выделяемых на целое число определяется его типом (short - короткие, long - длинные и т.д.) и конкретной реализацией языка.

Функционал сдвиговых операций заключается в том, что каждый бит в переменной заменяется соседним.

Направление зависит от вида сдвига, которых всего два: сдвиг вправо - “>>” и сдвиг влево - “<<”. Пример такого сдвига:

Значение b будет равно 512. То есть сдвиг вправо эквивалентен делению на 2, а сдвиг влево умножению на 2. Сдвиговые операции быстрее умножения и деления на 2 обычным способом.

При сдвигах вопрос вызывают крайние биты, для которых нет сдвигаемого значения или места в переменной. Например, если мы сдвинем влево переменную a на 6, мы получим что число 1024, а точнее 0000010000000000, выйдет из пределов unsigned short, а так же появятся биты, которые займут места первых 6 сдвинутых битов. На этот счет в C++ есть правило: если сдвигаемый бит нечем заменить, замена производится на 0. Так, же если сдвигаемый бит есть, а места под него нет, то есть выходит за границы типа, то возникает переполнение. Результат такой функции сильно зависит от используемой платформы, и применять такой подход не рекомендуется.

Аналогично и с числами со знаками. Использует ли их как еще 1 бит или просто откинет зависит от платформы.

В некоторых случаях можно избежать переполнения, используя автоопределение типа полученного числа. Работает только у целочисленных типов.

Тип b станет int, по правилам восходящих приведений типов в C++.

Опубликовано

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Капча загружается...