Эта статья требует дополнительных ссылок для проверки . ( декабрь 2009 г. ) ( Узнайте, как и когда удалить это сообщение-шаблон ) |
В комбинаторной математике , A циклический сдвиг представляет собой операцию перестановки записей в кортеж , либо путем перемещения окончательной записи в первой позиции, в то время как перемещение всех других записей в следующую позицию, или путем выполнения обратной операции. Циклический сдвиг - это особый вид циклической перестановки , которая, в свою очередь, представляет собой особый вид перестановки . Формально круговой сдвиг - это перестановка σ n элементов кортежа так, что либо
- по модулю n , для всех записей i = 1, ..., n
или же
- по модулю n для всех записей i = 1, ..., n .
Результат многократного применения круговых сдвигов к заданному кортежу также называется циклическим сдвигом кортежа.
Например, многократное применение круговых сдвигов к кортежу из четырех ( a , b , c , d ) последовательно дает
- ( г , а , б , в ),
- ( в , г , а , б ),
- ( б , в , г , а ),
- ( a , b , c , d ) (исходная четверка),
а затем последовательность повторяется; у этой четырехкортежности есть четыре различных круговых сдвига. Однако не все n -элементы имеют n различных круговых сдвигов. Например, кортеж из 4 ( a , b , a , b ) имеет только 2 различных круговых сдвига. В общем случае число круговых сдвигов в п -кратного может быть любой делитель из п , в зависимости от записей кортежа.
В компьютерном программировании , A вращения побитовое , также известный как циклический сдвиг, является операцией побитового , что сдвигает все биты операнда. В отличие от арифметического сдвига , циклический сдвиг не сохраняет знак целого ряда в бит или различать число с плавающей точкой «сек экспоненту от его мантиссы . В отличие от логического сдвига , свободные позиции битов не заполняются нулями, а заполняются битами, которые сдвинуты из последовательности.
Реализация круговых сдвигов [ править ]
Круговые сдвиги часто используются в криптографии для перестановки битовых последовательностей. К сожалению, многие языки программирования, включая C , не имеют операторов или стандартных функций для циклического сдвига, хотя практически все процессоры имеют для него побитовые инструкции (например, Intel x86 имеет ROL и ROR). Однако некоторые компиляторы могут предоставлять доступ к инструкциям процессора с помощью встроенных функций.. Кроме того, некоторые конструкции в стандартном коде ANSI C могут быть оптимизированы компилятором для «поворота» инструкции языка ассемблера на процессорах, которые имеют такую инструкцию. Большинство компиляторов C распознают следующую идиому и компилируют ее в одну 32-битную инструкцию поворота. [1] [2]
/ * * Операции сдвига в C определены только для значений сдвига, которые * не отрицательны и меньше sizeof (value) * CHAR_BIT. * Маска, используемая с поразрядным и (&), предотвращает неопределенное поведение *, когда счетчик сдвига равен 0 или> = ширина беззнакового int. * /#include <stdint.h> // для uint32_t, чтобы получить 32-битное вращение, независимо от размера int.#include <limits.h> // для CHAR_BITuint32_t rotl32 ( uint32_t значение , без знака INT счетчик ) { Const без знака Int маски = CHAR_BIT * SizeOf ( значения ) - 1 ; количество & = маска ; return ( значение << count ) | ( значение >> ( - количество и маска )); }uint32_t rotr32 ( uint32_t значение , без знака INT счетчик ) { Const без знака Int маски = CHAR_BIT * SizeOf ( значения ) - 1 ; количество & = маска ; возврат ( значение >> количество ) | ( значение << ( - количество и маска )); }
Это безопасный и составитель дружественный реализация была разработана Джоном Регер , [3] и далее полируется Питер Кордес. [4] [5]
Часто встречается более простая версия, когда диапазон count
ограничен от 1 до 31 бит:
uint32_t rotl32 ( uint32_t значение , неподписанные INT Количество ) { возвращение значение << подсчитывать | значение >> ( 32 - количество ); }
Эта версия опасна, потому что, если она count
равна 0 или 32, она запрашивает 32-битный сдвиг, что является неопределенным поведением в стандарте языка C. Тем не менее, он имеет тенденцию работать в любом случае, потому что большинство микропроцессоров реализуют value >> 32
либо 32-битный сдвиг (производящий 0), либо 0-битный сдвиг (производящий оригинал value
), и любой из них дает правильный результат в этом приложении.
Пример [ править ]
Если битовая последовательность 0001 0111 подверглась циклическому сдвигу на одну битовую позицию ... (см. Изображения ниже)
|
|
Если бы битовая последовательность 1001 0110 была подвергнута следующим операциям:
левый круговой сдвиг на 1 позицию: | 0010 1101 |
левый круговой сдвиг на 2 позиции: | 0101 1010 |
левый круговой сдвиг на 3 позиции: | 1011 0100 |
левый круговой сдвиг на 4 позиции: | 0110 1001 |
левый круговой сдвиг на 5 позиций: | 1101 0010 |
левый круговой сдвиг на 6 позиций: | 1010 0101 |
левый круговой сдвиг на 7 позиций: | 0100 1011 |
левый круговой сдвиг на 8 позиций: | 1001 0110 |
круговой сдвиг вправо на 1 позицию: | 0100 1011 |
правый круговой сдвиг на 2 позиции: | 1010 0101 |
правый круговой сдвиг на 3 позиции: | 1101 0010 |
правый круговой сдвиг на 4 позиции: | 0110 1001 |
правый круговой сдвиг на 5 позиций: | 1011 0100 |
правый круговой сдвиг на 6 позиций: | 0101 1010 |
правый круговой сдвиг на 7 позиций: | 0010 1101 |
правый круговой сдвиг на 8 позиций: | 1001 0110 |
Приложения [ править ]
Циклические коды - это разновидность блочного кода, обладающая тем свойством, что циклический сдвиг кодового слова всегда дает другое кодовое слово. Это мотивирует следующее общее определение: для строки s над алфавитом Σ пусть shift ( s ) обозначает набор круговых сдвигов s , а для набора L строк пусть shift ( L ) обозначает набор всех круговых сдвигов строк в L . Если L - циклический код, то shift ( L ) ⊆ L; это необходимое условие для того, чтобы L был циклическим языком . Операционный сдвиг ( L ) изучался в теории формального языка . Например, если L - контекстно-свободный язык , тогда shift ( L ) снова контекстно-свободный. [6] [7] Кроме того, если L описывается регулярным выражением длины n , существует регулярное выражение длины O ( n 3 ), описывающее сдвиг ( L ). [8]
См. Также [ править ]
- Переключатель ствола
- Побитовая операция
- Циркулянт
- Линдон слово
- Ожерелье - объект, похожий на кортеж, но для которого круговые смещения считаются эквивалентными.
Ссылки [ править ]
- ^ GCC: "Оптимизировать общие конструкции поворота"
- ^ «Очистка в коде объединителя ROTL / ROTR DAG» упоминает, что этот код поддерживает инструкцию «поворота» в CellSPU
- ^ Безопасный, эффективный и переносимый поворот в C / C ++
- ^ Stackoverflow: лучшие практики для ротации в C / C ++
- ^ Почти постоянное время вращения, которое не нарушает стандарты
- ^ T. Oshiba, "Свойство замыкания семейства контекстно-свободных языков при операции циклического сдвига", Transactions of IECE , 55D : 119–122, 1972.
- ^ А. Н. Маслов, "Операция циклического сдвига для языков", Проблемы передачи информации 9 : 333–338, 1973.
- ^ Грубер, Германн; Хольцер, Маркус (2009). «Языковые операции с регулярными выражениями полиномиального размера» (PDF) . Теоретическая информатика . 410 (35): 3281–3289. DOI : 10.1016 / j.tcs.2009.04.009 . Zbl 1176.68105 . Архивировано из оригинального (PDF) 29 августа 2017 года . Проверено 6 сентября 2012 ..