6. Как реализовать циклический сдвиг?
Автор ARV   
18.12.2009 г.
Операция циклического сдвига заключается в том, что бит, выталкиваемый слева (при сдвиге влево) переносится в самый младший разряд числа, а при сдвиге вправо наоборот, выталкиваемый справа переносится в самый старший разряд. То есть биты как бы путешествуют по кругу. В Си нет оператора, который бы выполнял циклический сдвиг, но используя простые сдвиги и двоичные битовые операции легко получить их аналоги. Циклический сдвиг байта на 1 разряд влево получается так:
var = (var << 1) | (var >> 7);

В этом примере значение переменной сдвигается влево на 1 разряд, а значение старшего бита переменной (который будет вытолкнут влево при сдвиге) переносится в младший разряд операцией сдвига вправо на 7 разрядов.

Для сдвига вправо на 1 разряд надо поступить аналогично:

var = (var >> 1) | (var << 7);

Удобно создать макросы для циклических сдвигов:

#define rolb_1(x) ((x << 1) | (x >> 7))
#define rorb_1(x) ((x >> 1) | (x << 7))

Однако, как быть, если надо сдвигать более чем на 1 разряд? Использовать вышеописанный макрос в цикле? Во многих случаях это приведет к неоправданному увеличению объема кода, лучше поступить так:

#define rolb(x,y) ((x << y) | (x >> (8 - y)))
#define rorb(x,y) ((x >> y) | (x << (8 - y)))

В этих макросах осуществляется циклический сдвиг x на y разрядов. Важно помнить, что x - байтовая переменная, поэтому y не может принимать значения больше 7.


Добавить в любимые (0) | Просмотров: 18143

  Ваш коментарий будет первым

Только зарегистрированные пользователи могут оставлять коментарии.
Пожалуйста зарегистрируйтесь или войдите в ваш аккаунт.