Круговой сдвиг

редактировать
Матрицы 8-элементных циклических сдвигов влево и вправо

В комбинаторной математике циклический сдвиг - это операция переупорядочения записей в кортеже кортеж, либо путем перемещения последней записи в первую позицию с одновременным перемещением всех других записей в следующую позицию, либо путем выполнения обратной операции. Циклический сдвиг - это особый вид циклической перестановки, которая, в свою очередь, представляет собой особый вид перестановки. Формально круговой сдвиг - это перестановка σ n элементов кортежа так, что либо

σ (i) ≡ (i + 1) {\ displaystyle \ sigma (i) \ Equiv (i +1)}\ sigma (i) \ Equiv (i + 1) по модулю n для всех записей i = 1,..., n

или

σ (i) ≡ (i - 1) {\ displaystyle \ sigma (i) \ Equiv (i-1)}\ sigma (i) \ Equiv (i-1) по модулю n для всех элементов i = 1,..., n.

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

Например, многократное применение круговых сдвигов к кортежу из четырех (a, b, c, d) последовательно дает

  • (d, a, b, c),
  • (c, d, a, b),
  • (b, c, d, a),
  • (a, b, c, d) (исходный кортеж из четырех),

а затем последовательность повторяется; Таким образом, этот набор из четырех имеет четыре различных круговых сдвига. Однако не все наборы из n имеют n различных циклических сдвигов. Например, кортеж из 4-х (a, b, a, b) имеет только 2 различных круговых сдвига. В общем, количество циклических сдвигов кортежа из n может быть любым делителем n, в зависимости от элементов кортежа.

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

Содержание
  • 1 Реализация круговых сдвигов
  • 2 Пример
  • 3 Приложения
  • 4 См. Также
  • 5 Ссылки
Реализация круговых сдвигов

Круговые сдвиги часто используются в криптография для перестановки битовых последовательностей. К сожалению, многие языки программирования, включая C, не имеют операторов или стандартных функций для циклического сдвига, хотя практически все процессоры имеют для него инструкции побитовой операции ( например, Intel x86 имеет ROL и ROR). Однако некоторые компиляторы могут предоставлять доступ к инструкциям процессора с помощью встроенных функций. Кроме того, некоторые конструкции в стандартном коде ANSI C могут быть оптимизированы компилятором для «поворота» инструкции языка ассемблера на процессорах, которые имеют такую ​​инструкцию. Большинство компиляторов C распознают следующую идиому и компилируют ее в одну 32-битную команду поворота.

/ * * Операции сдвига в C определены только для значений сдвига, которые * не отрицательны и меньше sizeof (value) * CHAR_BIT. * Маска, используемая с поразрядным и (), предотвращает неопределенное поведение *, когда счетчик сдвига равен 0 или>= ширина unsigned int. * / #include // для uint32_t, чтобы получить ротацию шириной 32 бита, независимо от размера int. #include // для CHAR_BIT uint32_t rotl32 (значение uint32_t, целое число без знака) {const unsigned int mask = CHAR_BIT * sizeof (значение) - 1; количество = маска; return (value << count) | (value>>(- count mask)); } uint32_t rotr32 (значение uint32_t, число целых чисел без знака) {const unsigned int mask = CHAR_BIT * sizeof (значение) - 1; количество = маска; возврат (значение>>количество) | (значение << (-count mask)); }

Эта безопасная и удобная для компилятора реализация была разработана Джоном Регером и далее доработана Питером Кордесом.

Более простая версия часто встречается, когда countограничен диапазоном от 1 до 31 бит:

uint32_t rotl32 (uint32_t value, unsigned int count) {return value << count | value>>(32 - count);}

Эта версия опасна, потому что если countравен 0 или 32, он запрашивает 32-битный сдвиг, что является undefined behavior в стандарте языка C. Однако он все равно работает, потому что большинство микропроцессоров реализуют value>>32как 32-битный сдвиг (производящий 0) или 0-битный сдвиг (производящий исходное значение), и любой из них дает правильный результат в этом приложении.

Пример

Если бы битовая последовательность 0001 0111 была подвергнута циклическому сдвигу на одну битовую позицию... (см. Изображения ниже)

  • влево даст: 0010 1110
Круговой сдвиг влево.
  • вправо даст: 1000 1011.
Правый круг

Если битовая последовательность 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) снова контекстно-свободный. Кроме того, если L описывается регулярным выражением длины n, существует регулярное выражение длины O (n), описывающее сдвиг (L).

См. также
Ссылки
Последняя правка сделана 2021-05-15 08:26:15
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте