Interested Article - Битовый сдвиг

Би́товый сдвиг — изменение позиций бит в машинном слове .

Большинство компьютеров не могут напрямую адресовать биты, которые содержатся группами по 8, 16, 32 или 64 бита в машинном слове . Для обеспечения работы с битами существует множество машинных инструкций , включающие различные типы сдвигов. Все сдвиги похожи друг на друга поведением средних битов, которые просто сдвигаются влево или вправо на определённую величину. Однако, поведение крайних битов, которые уходят из слова и которые появляются в слове, зависит от типа сдвига.

В электронике битовые сдвиги выполняются на сдвиговых регистрах .

Логический (беззнаковый) сдвиг

Логический сдвиг влево
Логический сдвиг вправо

Сдвиг, при котором уходящий бит исчезает, не влияя на оставшиеся биты, а на месте появившегося бита записывается бит 0 .

Пример работы операции сдвига:

  • Пусть у нас есть число двоичной системе ).
  • Если сделать сдвиг влево на 1 бит, то получим число .
  • Если сделать сдвиг исходного числа вправо на 1 бит, то получим число .

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

Арифметический (знаковый) сдвиг

Арифметический сдвиг влево
Арифметический сдвиг вправо

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

Пример № 1

Пример работы операции сдвига 8 битного числа в прямом коде:

  • Пусть у нас есть 8 битное число: 00000010b = 2. (записанное в двоичной системе , в прямом коде).
  • Cдвиг влево на 1 бит, даёт число: 00000100b = 4.
  • Сдвиг вправо на 1 бит, даёт число: 00000001b = 1.

Пример № 2

Пример работы операции сдвига 8 битного числа записанного в дополнительном до 2х коде:

  • Пусть у нас есть число 11111010b = −6 (в двоичной системе , в дополнительном коде).
  • Если сделать сдвиг влево на 1 бит, то получим число 11110100b = −12.
  • Если сделать сдвиг исходного числа вправо на 1 бит, то получим число 11111101b = −3.

Вывод

Легко заметить, что при арифметическом сдвиге сдвиг влево соответствует умножению на 2, а сдвиг вправо — делению на 2 (в общем случае — на основание системы счисления) с округлением к −∞. Например:

 1011 = −5          1111 = −1
>>a 1              >>a 1
 ----               ----
 1101 = −3          1111 = −1

Схемотехническая реализация операций сдвига очень проста. Именно поэтому эти операции рекомендуют использовать для операций умножения и деления целых чисел на числа, равные степени 2 (2, 4, 8, 16, 32, 64 и т. д.) — если, конечно, такое округление отрицательных чисел не мешает.

Циклический сдвиг

Циклический сдвиг влево
Циклический сдвиг вправо

При этом сдвиге уходящий бит появляется на месте появившегося свободного на другом конце числа.

Широко используется в криптографии.

Пример

  • Пусть у нас есть число 11111010b (в двоичной системе ).
  • Если сделать сдвиг влево на 1 бит, то получим число 11110101b.
  • Если сделать сдвиг исходного числа вправо на 1 бит, то получим число 01111101b.

Циклический сдвиг через бит переноса

Циклический сдвиг влево через бит переноса
Циклический сдвиг вправо через бит переноса

В архитектуру многих процессоров входит флаг переноса в следующий разряд (например, cf на x86 ). Данная операция выполняет циклический сдвиг над ( n +1)-битным числом, состоящим из регистра и флага переноса.

Например, если у нас в регистре число 11111010b, флаг переноса циклического сдвига вправо равен 0.

  • После сдвига влево на 1 бит в регистре 11110101b, флаг переноса равен 1.
  • Далее, после сдвига вправо на 1 бит в регистре 01111101b, флаг переноса равен 1.

Операция циклического сдвига через бит переноса используется при работе с многобайтовыми числами . В частности, чтобы сдвинуть вправо на 1 бит длинное число, нужно очистить cf (в случае деления числа со знаком нужно записать в cf старший бит старшего слова) и циклически сдвинуть на единицу через cf каждое слово, начиная с верхнего. Например, пусть у нас есть число 011000111100b, занимающее три 4-битных слова:

Было:              HI=0110, MED=0011, LO=1100, cf=0
После сдвига HI:   HI=0011, MED=0011, LO=1100, cf=0
После сдвига MED:  HI=0011, MED=0001, LO=1100, cf=1
После сдвига LO:   HI=0011, MED=0001, LO=1110, cf=0

Сдвиги через регистр флагов более чем на 1 бит практически не используются.

См. также

Примечания

  1. Можно вместо очистки флага для первого обрабатываемого слова использовать арифметический\логический сдвиг, если он присваивает флагу cf значение вышедшего бита.

Ссылки

Источник —

Same as Битовый сдвиг