MyTetra Share
Делитесь знаниями!
Реализация циклического сдвига ROR и ROL
Время создания: 18.02.2009 10:02
Текстовые метки: C, циклический сдвиг, ROR, ROL, бинарные операции
Раздел: Компьютер - Программирование - Язык C (Си)
Запись: xintrea/mytetra_syncro/master/base/0000000780/text.html на raw.github.com

Огромным недостатком языка Си (за который бы голову оторвать его создателям) является отсутствие операторов циклического битового сдвига, которые присутствуют практически на всех процессорах и без которых не обходится ни подсчет CRC32, ни вычисление корректирующих кодов Рида-Соломона, ни куча других подобных алгоритмов.


Некоторые программисты используют ассемблерные вставки, прибегая к непосредственному вызову команд процессора (на x86 это ROL/ROR – циклический битовый сдвиг влево и вправо соответственно), однако, такое решение делает программу непереносимой, причем, совершенно неоправданно непереносимой, поскольку, циклический сдвиг элементарно реализуется стандартными средствами Си.


Существует множество способов сделать это, вот только один из них. Не самый быстрый, требующий двух дополнительных переменных (хотя, в принципе, можно обойтись и одной), зато наглядный и универсальный, то есть работающий с переменными любой разрядности:


int rol(int a, int n)

{

int t1, t2;


n = n % (sizeof(a)*8); // нормализуем n

t1 = a << n; // двигаем а вправо на n бит, теряя старшие биты

t2 = a >> (sizeof(a)*8 - n); // перегоняем старшие биты в младшие


return t1 | t2; // объединяем старшие и младшие биты

}


int ror(int a, int n)

{

int t1, t2;


n = n % (sizeof(a)*8); // нормализуем n

t1 = a >> n; // двигаем а влево на n бит, теряя младшие биты

t2 = a << (sizeof(a)*8 - n); // перегоняем младшие биты в старшие


return t1 | t2; // объединяем старшие и младшие биты

}


Так же в этом разделе:
 
MyTetra Share v.0.65
Яндекс индекс цитирования