Разное

Битовая операция: Битовые операции в си (&, |, ^, ~, >)

Содержание

Битовые операции

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

Например, в языке программирования Паскаль обычные логические операции и логические операции над битами обозначают с помощью одних и тех же ключевых слов: not, and, or, xor. Компилятор определяет, что имелось в виду в зависимости от контекста использования этих слов. Обычные логические операции объединяют два и более простых логических выражения. Например, (a > 0) and (c != b), (c < a) or(not b) и т.п. В свою очередь побитовые логические операции выполняются исключительно над целыми числами (или переменными, которые их содержат). Например, a and b, a or 8, not 247.

Как понять побитовые операции

1. Переведем пару произвольных целых чисел до 256 (один байт) в двоичное представление.

     6710 = 0100 00112
    11410 =  0111 00102

2. Теперь расположим биты второго числа под соответствующими битами первого и выполним обычные логические операции к цифрам, стоящим в одинаковых разрядах первого и второго числа. Например, если в последнем (младшем) разряде одного числа стоит 1, а другого числа — 0, то логическая операция and вернет 0, а or вернет 1. Операцию not применим только к первому числу.

3. Переведем результат в десятичную систему счисления.

    01000010 = 26 + 21 = 64 + 2 = 66
    01110011 = 26 + 25 + 24 + 21 + 20 = 64 + 32 + 16 + 2 + 1 = 115
    00110001 = 25 + 24 + 20 = 32 + 16 + 1 = 49
    10111100 = 27 + 25 + 24 + 23 + 22 = 128 + 32 + 16 + 8 + 4 = 188
    

4. Итак, в результате побитовых логических операций получилось следующее:

    67 and 114 = 66
    67 or 114 = 115
    67 xor 114 = 49
    not 67 = 188
    

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

    5 and 6 = 4
    5 or 6 = 7
    5 xor 6 = 3
    not 5 = 250
    

Зачем нужны побитовые логические операции

Глядя на результат побитовых операций, не сразу можно уловить закономерности в их результате. Поэтому непонятно, зачем нужны такие операции. Однако, они находят свое применение. В байтах не всегда хранятся числа. Байт или ячейка памяти может хранить набор флагов (установлен — сброшен), представляющих собой информацию о состоянии чего-либо. С помощью битовых логических операций можно проверить, какие биты в байте установлены в единицу, можно обнулить биты или, наоборот, установить в единицу. Также существует возможность сменить значения битов на противоположные.

Проверка битов

Проверка битов осуществляется с помощью битовой логической операции and.

Представим, что имеется байт памяти с неизвестным нам содержимым. Известно, что логическая операция and возвращает 1, если только оба операнда содержат 1. Если к неизвестному числу применить побитовое логическое умножение (операцию and) на число 255 (что в двоичном представлении 1111 1111), то в результате мы получим неизвестное число. Обнулятся те единицы двоичного представления числа 255, которые будут умножены на разряды неизвестного числа, содержащие 0. Например, пусть неизвестное число 38 (0010 0110), тогда проверка битов будет выглядеть так:

Другими словами, x and 255 = x.

Обнуление битов

Чтобы обнулить какой-либо бит числа, нужно его логически умножить на 0.

Обратим внимание на следующее:

    1111 1110 = 254 = 255 - 1 = 255 - 20
    1111 1101 = 253 = 255 - 2 = 255 - 21
    1111 1011 = 251 = 255 - 4 = 255 - 22
    1111 0111 = 247 = 255 - 8 = 255 - 23
    1110 1111 = 239 = 255 - 16 = 255 - 24
    1101 1111 = 223 = 255 - 32 = 255 - 25
    1011 1111 = 191 = 255 - 64 = 255 - 26
    0111 1111 = 127 = 255 - 128 = 255 - 27

Т.е. чтобы обнулить четвертый с конца бит числа x, надо его логически умножить на 247 или на (255 — 23).

Установка битов в единицу

Для установки битов в единицу используется побитовая логическая операция or. Если мы логически сложим двоичное представление числа x с 0000 0000, то получим само число х. Но вот если мы в каком-нибудь бите второго слагаемого напишем единицу, то в результате в этом бите будет стоять единица.

Отметим также, что:

    0000 0001 = 20 = 1
    0000 0010 = 21 = 2
    0000 0100 = 22 = 4
    0000 1000 = 23 = 8
    0001 0000 = 24 = 16
    0010 0000 = 25 = 32
    0100 0000 = 26 = 64
    1000 0000 = 27 = 128
    

Поэтому, например, чтобы установить второй по старшинству бит числа x в единицу, надо его логически сложить с 64 (x or 64).

Смена значений битов

Для смены значений битов на противоположные используется битовая операция xor. Чтобы инвертировать определенный бит числа x, в такой же по разряду бит второго числа записывают единицу. Если же требуется инвертировать все биты числа x, то используют побитовую операцию исключающего ИЛИ (xor) с числом 255 (1111 1111).

Операции побитового циклического сдвига

Помимо побитовых логических операций во многих языках программирования предусмотрены битовые операции циклического сдвига влево или вправо. Например, в языке программирования Паскаль эти операции обозначаются shl(сдвиг влево) и shr (сдвиг вправо).

Первым операндом операций сдвига служит целое число, над которым выполняется операция. Во втором операнде указывается, на сколько позиций сдвигаются биты первого числа влево или вправо. Например, 105 shl 3 или 105 shr 4. Число 105 в двоичном представлении имеет вид 0110 1001.

При сдвиге влево теряются старшие биты исходного числа, на их место становятся младшие. Освободившиеся младшие разряды заполняются нулями.

При сдвиге вправо теряются младшие биты исходного числа, на их место становятся старшие. Освободившиеся старшие разряды заполняются нулями, если исходное число было положительным.

Битовая арифметика и операции над битами

В Pascal над целыми типами (byte, shortint, word, integer, longint и их диапазоны) допустимы побитовые операции.

Логические операции над битами

Над битами двух целых операндов можно выполнять ранее рассмотренные логические операции: not, and, or, xor. Отличие между побитовыми и логическими операциями состоит в том, что побитовые (поразрядные) операции выполняются над отдельными битами операндов, а не над их значением в десятичном (обычно) представлении.

Например, число 5 в двоичном представлении (в одном байте) имеет значение 00000101. Операция not инвертирует биты и мы получим 11111010, т.е число 250. Если побитовую операцию or использовать к числам 5 (00000101) и 3 (00000011), то получится число 7 (00000111).

Операции циклического сдвига

В Паскаль определены еще две операции над данными целого типа, имеющие тот же уровень приоритета, что и операции and, *, /, div и mod. Это операции shl и shr, которые сдвигают последовательность битов на заданное число позиций влево или вправо соответственно. При этом биты, которые выходят за разрядную сетку, теряются. При выполнении операции shl освободившиеся справа биты заполняются нулями. При выполнении операции shr освободившиеся слева биты заполняются единицами при сдвиге вправо отрицательных значений и нулями в случае положительных значений.

С помощью операции shl возможна замена операции умножения целых чисел на степени двойки. Следующие пары выражений приводят к одинаковому результату: (a shl 1) = a * 2, (a shl 2) = a * 4, (a shl3) = a * 8.

Пример побитовых операций и циклического сдвига

var
     A, B: byte;
begin
     A := 11;                                       {00001011}
     B := 6;                                         {00000110}
     writeln('A=', A);
     writeln('B=', B);
     writeln('not A = ', not A);           {11110100 = 244}
     writeln('A and B = ', A and B);   {00000010 = 2}
     writeln('A or B = ', A or B);        {00001111 = 15}
     writeln('A xor B = ', A xor B);    {00001101 = 13}
     writeln('A shl 1 = ', A shl 1);      {00010110 = 22}
     writeln('B shr 2 = ', B shr 2);      {00000001 = 1}
end.

Практическое значение побитовых операций

Операция and практически всегда используется только для достижения одной из двух целей: проверить наличие установленных в единицу битов или осуществить обнуление некоторых битов.

Подобная проверка нужна, если число представляет набор признаков с двумя возможными значениями (набор флагов). Так, многие системные ячейки памяти содержат сведения о конфигурации компьютера или его состоянии. При этом установка бита с конкретным номером в 1 трактуется как включение какого-либо режима, а в 0 — выключение этого режима.

Пусть переменная a имеет тип byte и является байтом с восемью флагами. Необходимо проверить состояние бита с номером 5 (биты нумеруются справа налево от 0 до 7). Единица в бите 5 — это пятая степень числа 2, т.е. 32 (00100000). Поэтому, если в пятом бите переменной a стоит единица, то выполняется условие (a and 32) = 32, которое можно проверить в операторе ветвления if. Если необходимо проверить состояние нескольких одновременно установленных в единицу битов, то нужно вычислить соответствующее число как сумму степеней числа 2, где показатели степени равны номерам битов, установленных в 1. Например, для битов 5, 2 и 0 имеем 32+4+1=37. Если a имеет среди прочих единицы в битах 5, 2, 0, то выполнится условие (a and 37) = 37.

Пусть нужно обнулить какой-либо бит в переменной a типа byte (например, бит 3). Определим сначала число, содержащее единицы во всех битах, кроме третьего. Максимальное число, которое можно записать в тип byte, равняется 255. Чтобы в нем обнулить третий бит, вычтем из этого числа третью степень числа 2 (255-8=247). Если это число логически умножить на a, то его единицы никак не скажутся на состоянии переменной a, а нуль в третьем бите независимо от значения третьего бита переменной a даст в результате 0. Итак, имеем a:= a and (255-8). Аналогично можно обнулить несколько битов.

Операция or применяется при установке в единицу отдельных битов двоичного представления целых чисел. Так, чтобы установить бит 4 переменной a в единицу без изменения остальных битов, следует записать a:= a or 16, где 16 — четвертая степень числа 2. Аналогично устанавливаются в единицу несколько битов.

Операция xor применяется для смены значения бита (или нескольких битов) на противоположное (1 на 0 или 0 на 1). Так, чтобы переключить в противоположное состояние 3-й бит переменной a, следует записать a:= a xor 8, где 8 — третья степень числа 2.

Побитовые операции. Программирование на C и C++

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

Основа вычислений

Двоичная цифровая система использует только две цифры — 0 и 1. Компьютеры работают в двоичном формате, что означает, что они хранят данные и выполняют вычисления, используя только нули и единицы.

Хотя одна бинарная цифра может использоваться для представления True (1) (истина) или False (0) (ложь) в логике, для хранения больших чисел и выполнения сложных функций можно использовать несколько двоичных цифр. Фактически любое число может быть представлено в двоичном формате.

Применение

Побитовые операторы используются в следующих областях:

  • Коммуникационные стеки, где отдельные биты в заголовке, прикрепленные к данным, несут важную информацию.

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

  • Низкоуровневое программирование для таких приложений, как драйверы устройств, криптографическое программное обеспечение, ПО для декодирования видео, распределители памяти, программное обеспечение для сжатия и графики.

  • Удобное ведение больших наборов целых чисел в задачах поиска и оптимизации.

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

Побитовые операции — как это работает?

В отличие от обычных логических операторов (например, +, -, *), которые работают с байтами или группами байтов, побитовые операторы могут проверять или устанавливать каждый из отдельных битов в байте. Побитовые операции никогда не вызывают переполнения в ячейках памяти, потому что результат, полученный после выполнения операции, находится в пределах диапазона возможных значений для числового типа.

Побитовые операторы, используемые в семействе языков C (C #, C и C ++):

  • OR (|) — результат является истиной, если любой из операндов истинен.

  • AND (&) — результат верен, только если оба операнда верны. Его можно использовать для настройки маски проверки значений определенных битов.

  • XOR (^) — результат является истиной, только если один из его операндов истинен. Он используется, в основном, для переключения определенных бит. Он также помогает заменять две переменные без использования третьей.

  • NOT (~) — побитовое дополнение или инверсия. Предоставляет поразрядное дополнение к операнду путем инвертирования его значения, так что все нули превращаются в единицы, а все единицы превращаются в нули.

  • >> (Right-Shift) и << (Left-Shift) — оператор, который перемещает биты в число позиций, заданных вторым операндом в правом или левом направлении. Операторы сдвига используются для выравнивания битов.

Пример работы

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

Логическая операция AND (&) каждой битовой пары приводит к 1 (истине), если первый и второй биты равны 1. В противном случае результат равен нулю. Среди других применений AND может использоваться для проверки отдельных битов в битовой строке, чтобы увидеть, являются ли они ложным или истинным значением.

Рассмотрим подробнее на примере:

IsOdd = (ValueToTest & 1)! = 0.

Логическая операция ИЛИ (|) каждой битовой пары приводит к 1, если первый или второй бит равен 1. В противном случае результат равен нулю. Логическая операция XOR (~) каждой битовой пары приводит к 1, если два бита различны, и 0, если они одинаковы.

Логический оператор NOT представлен как ^. Левый сдвиг (<<), правый сдвиг (>>) и правый сдвиг нулевой заливки (>>>>) иногда упоминаются как побитовые операторы и называются операторами сдвига бит.

Приоритезация

Порядок приоритетности (от наивысшего до самого низкого) в побитовых операторах при программировании на C:

Данные операнды используются в большинстве языков программирования. Например, при написании кода в Javascript побитовые операции будет теми же, что и вышеперечисленные. Это вызвано базовыми математическими основами, на которых базируется программный код. В частности, побитовые операции в Java, в свою очередь, полностью тождественны Javascript.

Бит и программирование на C и других языках

Бит является наименьшей единицей измерения, используемой для количественной оценки компьютерных данных. Он содержит одно двоичное значение — 0 или 1.
Хотя один бит может определять логическое значение True (1) или False (0), как отдельная единица он используется редко. Поэтому в компьютерном хранилище биты часто группируются в 8-битные кластеры, называемые байтами. Поскольку байт содержит восемь бит, каждый из которых имеет два возможных значения, в побитовых операциях в Си (язык программирования) один байт может иметь 28 или 256 различных значений.

Термины «биты» и «байты» часто путаются и даже используются взаимозаменяемо, поскольку звучат одинаково и оба сокращаются буквой «Б». Однако при правильном написании биты сокращаются в нижнем регистре «b», а байты сокращаются в верхнем регистре — «B». Важно не путать эти два термина, так как любое измерение в байтах содержит в восемь раз больше бит. Например, небольшой текстовый файл размером 4 КБ содержит 4000 байт или 32 000 бит.

Как правило, файлы, устройства хранения и емкость хранилища измеряются в байтах, а скорости передачи данных измеряются в битах. Например, карта памяти SSD может иметь емкость 240 ГБ, тогда как загрузка может переноситься со скоростью 10 Мбит/с. Кроме того, биты также используются для описания архитектуры процессора, такой как 32-разрядный или 64-разрядный процессор.

Побитовые операции в паскале

Побитовый уровень операций в паскале включает в себя работу с отдельными битами, которые являются наименьшими единицами данных на компьютере. Хотя компьютеры способны манипулировать битами, они обычно хранят данные и выполняют инструкции в битовых кратных значениях, называемых байтами. Большинство языков программирования, в том числе побитовые операции в Delphi, управляют группами из 8, 16 или 32 бит.

Описание процесса

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

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

  • шифрование;

  • сжатие;

  • графику;

  • связь по портам/сокетам;

  • программирование встроенных систем;

  • машины с конечным состоянием.

Побитовый оператор работает с двоичным представлением числа, а не с его значением. Операнд рассматривается как набор бит, а не как один номер. Побитовые операторы аналогичны в большинстве поддерживающих их языков — C, Java, JavaScript, Python и Visual Basic.

Почему это важно использовать?

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

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

Как понять побитовые операции





⇐ ПредыдущаяСтр 8 из 19Следующая ⇒

1. Переведем пару произвольных целых чисел до 256 (один байт) в двоичное представление.

2. 6710 = 0100 00112

3. 11410 = 0111 00102

 

4. Теперь расположим биты второго числа под соответствующими битами первого и выполним обычные логические операции к цифрам, стоящим в одинаковых разрядах первого и второго числа. Например, если в последнем (младшем) разряде одного числа стоит 1, а другого числа — 0, то логическая операция and вернет 0, а or вернет 1. Операцию not применим только к первому числу.

5. Переведем результат в десятичную систему счисления.

6. 01000010 = 26 + 21 = 64 + 2 = 66

7. 01110011 = 26 + 25 + 24 + 21 + 20 = 64 + 32 + 16 + 2 + 1 = 115

8. 00110001 = 25 + 24 + 20 = 32 + 16 + 1 = 49

9. 10111100 = 27 + 25 + 24 + 23 + 22 = 128 + 32 + 16 + 8 + 4 = 188

10. Итак, в результате побитовых логических операций получилось следующее:

11.67 and 114 = 66

12.67 or 114 = 115

13.67 xor 114 = 49

14.not 67 = 188

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

5 and 6 = 4

5 or 6 = 7

5 xor 6 = 3

not 5 = 250

Зачем нужны побитовые логические операции

Глядя на результат побитовых операций, не сразу можно уловить закономерности в их результате. Поэтому непонятно, зачем нужны такие операции. Однако, они находят свое применение. В байтах не всегда хранятся числа. Байт или ячейка памяти может хранить набор флагов (установлен — сброшен), представляющих собой информацию о состоянии чего-либо. С помощью битовых логических операций можно проверить, какие биты в байте установлены в единицу, можно обнулить биты или, наоборот, установить в единицу. Также существует возможность сменить значения битов на противоположные.

Проверка битов

Проверка битов осуществляется с помощью битовой логической операции and.

Представим, что имеется байт памяти с неизвестным нам содержимым. Известно, что логическая операция and возвращает 1, если только оба операнда содержат 1. Если к неизвестному числу применить побитовое логическое умножение (операцию and) на число 255 (что в двоичном представлении 1111 1111), то в результате мы получим неизвестное число. Обнулятся те единицы двоичного представления числа 255, которые будут умножены на разряды неизвестного числа, содержащие 0. Например, пусть неизвестное число 38 (0010 0110), тогда проверка битов будет выглядеть так:



Другими словами, x and 255 = x.

Обнуление битов

Чтобы обнулить какой-либо бит числа, нужно его логически умножить на 0.

Обратим внимание на следующее:

1111 1110 = 254 = 255 — 1 = 255 — 20

1111 1101 = 253 = 255 — 2 = 255 — 21

1111 1011 = 251 = 255 — 4 = 255 — 22

1111 0111 = 247 = 255 — 8 = 255 — 23

1110 1111 = 239 = 255 — 16 = 255 — 24

1101 1111 = 223 = 255 — 32 = 255 — 25

1011 1111 = 191 = 255 — 64 = 255 — 26

0111 1111 = 127 = 255 — 128 = 255 — 27

Т.е. чтобы обнулить четвертый с конца бит числа x, надо его логически умножить на 247 или на (255 — 23).

Установка битов в единицу

Для установки битов в единицу используется побитовая логическая операция or. Если мы логически сложим двоичное представление числа x с 0000 0000, то получим само число х. Но вот если мы в каком-нибудь бите второго слагаемого напишем единицу, то в результате в этом бите будет стоять единица.

Отметим также, что:

0000 0001 = 20 = 1

0000 0010 = 21 = 2

0000 0100 = 22 = 4

0000 1000 = 23 = 8

0001 0000 = 24 = 16

0010 0000 = 25 = 32

0100 0000 = 26 = 64

1000 0000 = 27 = 128

Поэтому, например, чтобы установить второй по старшинству бит числа x в единицу, надо его логически сложить с 64 (x or 64).

Смена значений битов

Для смены значений битов на противоположные используется битовая операция xor. Чтобы инвертировать определенный бит числа x, в такой же по разряду бит второго числа записывают единицу. Если же требуется инвертировать все биты числа x, то используют побитовую операцию исключающего ИЛИ (xor) с числом 255 (1111 1111).

Операции побитового циклического сдвига

Помимо побитовых логических операций во многих языках программирования предусмотрены битовые операции циклического сдвига влево или вправо. Например, в языке программирования Паскаль эти операции обозначаются shl (сдвиг влево) и shr (сдвиг вправо).

Первым операндом операций сдвига служит целое число, над которым выполняется операция. Во втором операнде указывается, на сколько позиций сдвигаются биты первого числа влево или вправо. Например, 105 shl 3 или 105 shr 4. Число 105 в двоичном представлении имеет вид 0110 1001.

При сдвиге влево теряются старшие биты исходного числа, на их место становятся младшие. Освободившиеся младшие разряды заполняются нулями.




При сдвиге вправо теряются младшие биты исходного числа, на их место становятся старшие. Освободившиеся старшие разряды заполняются нулями, если исходное число было положительным.











O.2 — Побитовые операторы | Изучите C ++

Поразрядные операторы

C ++ предоставляет 6-битные операторы манипуляции, часто называемые побитовыми операторами:

Оператор Символ Форма Операция
левое смещение << x << y все биты в x сдвинуты влево биты y
сдвиг вправо >> x >> y все биты в x сдвинуты вправо биты y
побитовое НЕ ~ ~ х все биты в x перевернуты
побитовое И и x & y каждый бит в x И каждый бит в y
побитовое ИЛИ | x | y каждый бит в x ИЛИ каждый бит в y
побитовое XOR ^ х ^ у каждый бит в x XOR каждый бит в y

В следующих примерах мы в основном будем работать с 4-битными двоичными значениями.Это сделано для удобства и простоты примеров. В реальных программах количество используемых битов зависит от размера объекта (например, 2-байтовый объект будет хранить 16 бит).

Для удобства чтения мы также опустим префикс 0b вне примеров кода (например, вместо 0b0101 мы будем использовать просто 0101).

Операторы побитового сдвига влево (<<) и побитового сдвига вправо (>>)

Оператор побитового сдвига влево (<<) сдвигает биты влево.Левый операнд - это выражение для сдвига битов, а правый операнд - это целое число бит, на которое нужно сдвинуть влево.

Итак, когда мы говорим x, мы говорим «сдвинуть биты в переменной x влево на 1 место». Новые биты, сдвинутые с правой стороны, получают значение 0.

0011 << 1 - 0110
0011 << 2 - 1100
0011 << 3 - 1000

Обратите внимание, что в третьем случае мы немного сдвинули конец числа! Биты, сдвинутые с конца двоичного числа, теряются навсегда.

Оператор побитового сдвига вправо (>>) сдвигает биты вправо.

1100 >> 1 — 0110
1100 >> 2 — 0011
1100 >> 3 — 0001

Обратите внимание, что в третьем случае мы немного сдвинулись с правого конца числа, поэтому оно потеряно.

Вот пример некоторого сдвига бит:

#include

#include

int main ()

{

std :: bitset <4> x {0b1100};

std :: cout << x << '\ n';

std :: cout << (x >> 1) << '\ n'; // сдвинуть вправо на 1, получив 0110

std :: cout << (x << 1) << '\ n'; // сдвинуть влево на 1, получив 1000

return 0;

}

Это отпечатки:

1100
0110
1000
 

Обратите внимание, что результаты применения операторов побитового сдвига к целому числу со знаком зависят от компилятора до C ++ 20.

До C ++ 20 не сдвигайте целое число со знаком (и даже в этом случае, вероятно, все же лучше использовать беззнаковое)

Что !? Разве оператор << и оператор >> не используются для ввода и вывода?

Да, конечно.

Сегодняшние программы обычно не очень часто используют операторы побитового сдвига влево и вправо для сдвига битов. Скорее, вы склонны видеть оператор побитового сдвига влево, используемый с std :: cout для вывода текста. Рассмотрим следующую программу:

#include

#include

int main ()

{

unsigned int x {0b0100};

х = х << 1; // использовать оператор << для сдвига влево

std :: cout << std :: bitset <4> {x}; // использовать оператор << для вывода

return 0;

}

Эта программа напечатает:

1000
 

В приведенной выше программе, как оператор << знает, что нужно сдвигать биты в одном случае и выводить x в другом случае? Ответ заключается в том, что std :: cout имеет перегруженных (при условии альтернативного определения) operator <<, который выполняет вывод консоли, а не сдвиг бит.

Когда компилятор видит, что левым операндом оператора << является std :: cout, он знает, что он должен вызвать версию оператора <<, которая перегружена std :: cout для вывода. Если левый операнд является целым типом, то operator << знает, что он должен выполнять обычное поведение сдвига битов.

То же самое для оператора >>.

Обратите внимание, что если вы используете оператор << как для вывода, так и для сдвига влево, требуется заключение в скобки:

#include

#include

int main ()

{

std :: bitset <4> x {0b0110};

std :: cout << x << 1 << '\ n'; // выводим значение x (0110), затем 1

std :: cout << (x << 1) << '\ n'; // вывод x со сдвигом влево на 1 (1100)

return 0;

}

Это отпечатки:

01101
1100
 

В первой строке печатается значение x (0110), а затем литерал 1.Вторая строка выводит значение x со смещением влево на 1 (1100).

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

Побитовое НЕ

Побитовый оператор НЕ (~), пожалуй, самый простой для понимания из всех побитовых операторов. Он просто переворачивает каждый бит с 0 на 1 или наоборот. Обратите внимание, что результат побитовое НЕ зависит от размера вашего типа данных.

Переворот 4 бита:
~ 0100 — 1011

Переворачивание 8 бит:
~ 0000 0100 это 1111 1011

И в 4-битном, и в 8-битном случае мы начинаем с одного и того же числа (двоичное 0100 такое же, как 0000 0100, точно так же, как десятичное 7 такое же, как 07), но в итоге получаем другой результат .

Мы можем увидеть это в действии в следующей программе:

#include

#include

int main ()

{

std :: cout << std :: bitset <4> {~ 0b0100u} << '' << << std :: bitset <8> {~ 0b0100u};

возврат 0;

}

Эти отпечатки:
1011 11111011

Побитовое ИЛИ

Побитовое ИЛИ (|) работает так же, как его аналог логическое ИЛИ .Однако вместо применения OR к операндам для получения единственного результата, побитовое OR применяется к каждому биту! Например, рассмотрим выражение 0b0101 | 0b0110 .

Для выполнения (любых) побитовых операций проще всего выровнять два операнда следующим образом:

0 1 0 1 ИЛИ
0 1 1 0
 

, а затем примените операцию к каждому столбцу битов.

Если вы помните, логическое ИЛИ оценивается как истина (1) , если левый, правый или оба операнда равны истина (1) , и 0 в противном случае. Побитовое ИЛИ оценивается как 1 , если левый, правый или оба бита равны 1 , и 0 в противном случае. Следовательно, выражение оценивается так:

0 1 0 1 ИЛИ
0 1 1 0
-------
0 1 1 1
 

Наш результат — 0111 двоичный.

#include

#include

int main ()

{

std :: cout << (std :: bitset <4> {0b0101} | std :: bitset < 4> {0b0110});

возврат 0;

}

Это отпечатки:

0111
 

То же самое можно сделать и с составными выражениями ИЛИ, например 0b0111 | 0b0011 | 0b0001 .Если любой из битов в столбце равен 1 , результат этого столбца будет 1 .

0 1 1 1 ИЛИ
0 0 1 1 ИЛИ
0 0 0 1
--------
0 1 1 1
 

Вот код для вышеуказанного:

#include

#include

int main ()

{

std :: cout << (std :: bitset <4> {0b0111} | std :: bitset < 4> {0b0011} | std :: bitset <4> {0b0001});

возврат 0;

}

Это отпечатки:

0111
 

Побитовое И

Побитовое И (&) работает аналогично приведенному выше. Логическое И оценивается как истина, если и левый, и правый операнды оценивают как истинное значение . Побитовое И оценивается как истина (1) , если оба бита в столбце равны 1 . Рассмотрим выражение 0b0101 & 0b0110 . Выравнивание каждого из битов и применение операции И к каждому столбцу битов:

0 1 0 1 И
0 1 1 0
--------
0 1 0 0
 

#include

#include

int main ()

{

std :: cout << (std :: bitset <4> {0b0101} & std :: bitset < 4> {0b0110});

возврат 0;

}

Это отпечатки:

0100
 

Точно так же мы можем сделать то же самое с составными выражениями AND, такими как 0b0001 & 0b0011 & 0b0111 .Если все биты в столбце равны 1, результат этого столбца будет 1.

0 0 0 1 И
0 0 1 1 И
0 1 1 1
--------
0 0 0 1
 

#include

#include

int main ()

{

std :: cout << (std :: bitset <4> {0b0001} & std :: bitset < 4> {0b0011} & std :: bitset <4> {0b0111});

возврат 0;

}

Это отпечатки:

0001
 

Побитовое исключающее ИЛИ

Последний оператор — это побитовое исключающее ИЛИ (^), также известное как исключающее или.0b0111 . Если в столбце есть четное число 1 бит, результат будет 0 . Если в столбце нечетное количество битов, равное 1, результатом будет 1 .

0 0 0 1 XOR
0 0 1 1 XOR
0 1 1 1
--------
0 1 0 1
 

Операторы побитового присваивания

Подобно операторам арифметического присваивания, C ++ предоставляет операторы побитового присваивания, чтобы упростить изменение переменных.

Оператор Символ Форма Операция
Назначение левой смены << = х Сдвиг x влево на бит y
Назначение правой смены >> = х >> = у Сдвиг x вправо на биты y
Назначение побитового ИЛИ | = х | = у Назначить x | от y до x
Побитовое И присваивание & = x & = y Назначьте x и y на x
Поразрядное присвоение XOR ^ = х ^ = у Назначьте x ^ y на x

Например, вместо записи x = x >> 1; , можно написать x >> = 1; .

#include

#include

int main ()

{

std :: bitset <4> бит {0b0100};

бит >> = 1;

std :: cout << bits;

возврат 0;

}

Эта программа напечатает:

0010
 

Сводка

Обобщение того, как оценивать побитовые операции с использованием метода столбцов:

При оценке поразрядным ИЛИ , если какой-либо бит в столбце равен 1, результат для этого столбца равен 1.
При оценке поразрядного И , если все биты в столбце равны 1, результат для этого столбца равен 1.
При оценке поразрядного ИСКЛЮЧАЮЩЕГО ИЛИ , если в столбце есть нечетное число 1 бит, результат для этого столбец 1.

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

Время викторины

а) Что дает 0110 >> 2 в двоичном формате?

Показать решение

0110 >> 2 оценивается как 0001

b) Что дает следующее двоичное значение: 0011 | 0101?

Показать решение

0 0 1 1 ИЛИ
0 1 0 1
--------
0 1 1 1
 

c) Что означает следующее в двоичном формате: 0011 и 0101?

Показать решение

0 0 1 1 И
0 1 0 1
--------
0 0 0 1
 

d) Что означает следующее в двоичном формате (0011 | 0101) и 1001?

Показать решение

В скобках:

0 0 1 1 ИЛИ
0 1 0 1
--------
0 1 1 1

Потом:

0 1 1 1 И
1 0 0 1
--------
0 0 0 1
 

Побитовое вращение похоже на побитовый сдвиг, за исключением того, что любые биты, сдвинутые с одного конца, добавляются обратно к другому концу.Например 0b1001. Для этого можно использовать test () и set ().

Должен выполняться следующий код:

1

2

3

4

5

6

7

8

9

10

11

12

13

140002

14

18

19

#include

#include

// «rotl» означает «повернуть влево»

std :: bitset <4> rotl (std :: bitset <4> бит)

{

// Ваш код здесь

}

int main ()

{

std :: bitset <4> bits1 {0b0001};

std :: cout << rotl (bits1) << '\ n';

std :: bitset <4> bits2 {0b1001};

std :: cout << rotl (bits2) << '\ n';

возврат 0;

}

и выведите следующее:

0010
0011
 

Показать решение

1

2

3

4

5

6

7

8

9

10

11

12

13

140002

14

18

19

20

21

22

23

24

25

#include

#include

std :: bitset <4> rotl (std :: bitset <4> bits)

{

bool leftbit = bits.тест (3);

бит << = 1; // сдвиг влево

if (leftbit)

bits.set (0);

бит возврата;

}

int main ()

{

std :: bitset <4> bits1 {0b0001};

std :: cout << rotl (bits1) << '\ n';

std :: bitset <4> bits2 {0b1001};

std :: cout << rotl (bits2) << '\ n';

возврат 0;

}

Мы назвали функцию «rotl», а не «rotateLeft», потому что «rotl» — это хорошо известное имя в информатике, а также имя стандартной функции std :: rotl .

Дополнительный балл: повторите тест №2, но не используйте функции проверки и установки.

Показать решение

1

2

3

4

5

6

7

8

9

10

11

12

13

140002

14

18

19

20

21

#include

#include

// ч / т для ридера Криса для этого решения

std :: bitset <4> rotl (std :: bitset <4> бит)

{

// бит << 1 сдвиг влево

// биты >> 3 обрабатывают поворот самого левого бита

return (биты << 1) | (биты >> 3);

}

int main ()

{

std :: bitset <4> bits1 {0b0001};

std :: cout << rotl (bits1) << '\ n';

std :: bitset <4> bits2 {0b1001};

std :: cout << rotl (bits2) << '\ n';

возврат 0;

}

.

Битовые операторы C ++

В C ++ побитовые операторы выполняют операции с целочисленными данными на индивидуальном битовом уровне. Эти операции включают тестирование, установку или сдвиг фактических битов. Например,

  а и б;
а | б;  

Вот список из 6 побитовых операторов, включенных в C ++.

Оператор Описание
и Оператор побитового И
| Оператор побитового ИЛИ
^ Побитовый оператор XOR
~ Оператор побитового дополнения
<< Оператор побитового сдвига влево
>> Оператор побитового сдвига вправо

Эти операторы необходимы, потому что арифметико-логический блок (ALU), присутствующий в ЦП компьютера, выполняет арифметические операции на битовом уровне.

Примечание: Побитовые операторы могут использоваться только вместе с типами данных char и int .


1. Оператор побитового И в C ++

Поразрядный оператор AND и возвращает 1 тогда и только тогда, когда оба операнда равны 1 . В противном случае возвращается 0 .

Следующая таблица демонстрирует работу побитового оператора AND. Пусть a и b будут двумя операндами, которые могут принимать только двоичные значения i.е. 1 и 0 .

а б a & b
0 0 0
0 1 0
1 0 0
1 1 1

Примечание: Приведенная выше таблица известна как «Таблица истинности» для побитового оператора AND.

Давайте посмотрим на операцию побитового И двух целых чисел 12 и 25:

12 = 00001100 (в двоичном формате)

25 = 00011001 (в двоичном формате)

// Побитовое И Операция 12 и 25

     00001100
& 00011001
     _________
     00001000 = 8 (в десятичной системе) 

Пример 1: Побитовое И

  #include 
используя пространство имен std;

int main () {
    // объявляем переменные
    int a = 12, b = 25;

    cout << "a =" << a << endl;
    cout << "b =" << b << endl;
    cout << "a & b =" << (a & b) << endl;

    возврат 0;
}  

Выход

  а = 12
б = 25
а & b = 8  

В приведенном выше примере мы объявили две переменные a и b .Обратите внимание на строку

.

  cout << "a & b =" << (a & b) << endl;  

Здесь мы выполняем поразрядно и между переменными a и b .


2. Оператор побитового ИЛИ в C ++

Поразрядное ИЛИ | Оператор возвращает 1 , если хотя бы один из операндов - 1 . В противном случае возвращается 0 .

Следующая таблица истинности демонстрирует работу побитового оператора ИЛИ.Пусть a и b будут двумя операндами, которые могут принимать только двоичные значения, то есть 1 или 0 .

а б a | б
0 0 0
0 1 1
1 0 1
1 1 1

Давайте посмотрим на побитовую операцию ИЛИ двух целых чисел 12 и 25 :

12 = 00001100 (в двоичном формате)
25 = 00011001 (в двоичном формате)

Побитовое ИЛИ для 12 и 25
    00001100
| 00011001
    _________
    00011101 = 29 (в десятичной системе) 

Пример 2: Побитовое ИЛИ

  #include 

int main () {
    int a = 12, b = 25;

    cout << "a =" << a << endl;
    cout << "b =" << b << endl;
    cout << "a | b =" << (a | b) << endl;

    возврат 0;
}  

Выход

  а = 12
б = 25
а | б = 29  

Поразрядное число или из a = 12 и b = 25 дает 29 .Оператор возвращает 1 тогда и только тогда, когда один из операндов равен 1 . Однако, если оба операнда - 0 или оба - 1 , то результат будет 0 .

Следующая таблица истинности демонстрирует работу побитового оператора ИЛИ. Пусть a и b будут двумя операндами, которые могут принимать только двоичные значения, то есть 1 или 0 .

а б а ^ б
0 0 0
0 1 1
1 0 1
1 1 0

Давайте посмотрим на побитовую операцию XOR двух целых чисел 12 и 25:

12 = 00001100 (в двоичном формате)
25 = 00011001 (в двоичном формате)

Побитовая операция XOR 12 и 25
    00001100
^ 00011001
    _________
    00010101 = 21 (в десятичной системе) 

Пример 3: Побитовое исключающее ИЛИ

  #include 

int main () {
    int a = 12, b = 25;

    cout << "a =" << a << endl;
    cout << "b =" << b << endl;
    cout << "a ^ b =" << (a ^ b) << endl;

    возврат 0;
}  

Выход

  а = 12
б = 25
а ^ Ь = 21  

Поразрядный xor для a = 12 и b = 25 дает 21 .


4. Оператор поразрядного дополнения C ++

Оператор поразрядного дополнения - это унарный оператор (работает только с одним операндом). Он обозначается цифрами ~ , что изменяет двоичные цифры 1 на 0 и 0 на 1 .

Побитовое дополнение

Важно отметить, что побитовое дополнение любого целого числа N равно - (N + 1) . Например,

Рассмотрим целое число 35 .Согласно правилу, побитовое дополнение 35 должно быть - (35 + 1) = -36 . Теперь посмотрим, получим ли мы правильный ответ или нет.

35 = 00100011 (в двоичном формате)

// Использование оператора побитового дополнения
~ 00100011
 __________
  11011100 

В приведенном выше примере мы получаем, что поразрядное дополнение 00100011 ( 35 ) равно 11011100 . Здесь, если преобразовать результат в десятичный формат, мы получим 220 .

Однако важно отметить, что мы не можем напрямую преобразовать результат в десятичный формат и получить желаемый результат.Это связано с тем, что двоичный результат 11011100 также эквивалентен -36 .

Чтобы понять это, нам сначала нужно вычислить двоичный выход -36 . Мы используем дополнение до 2 для вычисления двоичного числа отрицательных целых чисел.


Дополнение до двух

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

Например,

36 = 00100100 (в двоичном формате)

Дополнение до 1 = 11011011

Дополнение 2:
11011011
 +1
_________
11011100 

Здесь мы видим дополнение до 2 36 (то есть -36 ) - это 11011100 . Это значение эквивалентно поразрядному дополнению 35 .

Следовательно, мы можем сказать, что поразрядное дополнение для 35 составляет -36 .


Пример 4: Побитовое дополнение

  #include 

int main () {
    int num1 = 35;
    int num2 = -150;
    cout << "~ (" << num1 << ") =" << (~ num1) << endl;
    cout << "~ (" << num2 << ") =" << (~ num2) << endl;

    возврат 0;
}  

Выход

  ~ (35) = -36
~ (-150) = 149  

В приведенном выше примере мы объявили две целочисленные переменные num1 и num2 и инициализировали их значениями 35 и -150 соответственно.

Затем мы вычислили их поразрядное дополнение с кодами (~ num1) и (~ num2) соответственно и отобразили их на экране.

Поразрядное дополнение до 35 = - (35 + 1) = -36
т.е. ~ 35 = -36

Поразрядное дополнение -150 = - (-150 + 1) = - (-149) = 149
т.е. ~ (-150) = 149 

Это именно то, что мы получили на выходе.


Операторы сдвига C ++

В программировании на C ++ есть два оператора сдвига:

  • Оператор правого переключения >>
  • Оператор левой смены <<

5.Оператор сдвига вправо в C ++

Оператор сдвига вправо сдвигает все биты вправо на определенное количество указанных битов. Обозначается он >> .

Когда мы сдвигаем любое число вправо, младшие значащие биты отбрасываются, а старшие значащие биты заменяются нулями.

one bit Right Shift

Как видно из изображения выше, у нас есть 4-значное число. Когда мы выполняем операцию сдвига вправо на один бит, каждый отдельный бит сдвигается вправо на 1 бит.

В результате крайний правый бит отбрасывается, а крайний левый бит остается свободным. Эта вакансия заменяется на 0 .


6. Оператор левого сдвига в C ++

Оператор сдвига влево сдвигает все биты влево на определенное количество заданных битов. Обозначается он << .

one bit Left Shift

Как видно из изображения выше, у нас есть 4-значное число. Когда мы выполняем операцию сдвига влево на 1 бит, каждый отдельный бит сдвигается влево на 1 бит.

В результате самый левый бит отбрасывается, а самый правый бит остается свободным. Эта вакансия заменяется на 0 .


Пример 5: Операторы смены

  #include 

int main () {

    // объявление двух целочисленных переменных
    int num = 212, я;

    // Сдвиг вправо
    cout << "Сдвиг вправо:" << endl;

    // Использование цикла for для сдвига числа вправо с 0 бит на 3 бит
    for (i = 0; i <4; i ++) {
        cout << "212 >>" << i << "=" << (212 >> i) << endl;
    }

    // Сдвиг влево
    cout << "\ nСдвиг влево:" << endl;

    // Использование цикла for для сдвига числа слева от 0 бит до 3 бит
    for (i = 0; i <4; i ++) {
        cout << "212 <<" << i << "=" << (212 << i) << endl;
    }

    возврат 0;
}  

Выход

  Сдвиг вправо:
212 >> 0 = 212
212 >> 1 = 106
212 >> 2 = 53
212 >> 3 = 26

Сдвиг влево:
212 << 0 = 212
212 << 1 = 424
212 << 2 = 848
212 << 3 = 1696  

Из вывода вышеприведенной программы мы можем сделать вывод, что для любого числа N результат оператора сдвига вправо:

N >> 0 = N
N >> 1 = (N >> 0) / 2
N >> 2 = (N >> 1) / 2
N >> 3 = (N >> 2) / 2 

и так далее.

Аналогично, результат оператора сдвига влево:

N << 0 = N
N << 1 = (N << 0) * 2
N << 2 = (N << 1) * 2
N << 3 = (N << 2) * 2 

и так далее.

Отсюда можно заключить, что

N >> m = [N >> (m-1)] / 2
N << m = [N << (m-1)] * 2 

.

Kotlin побитовые операции и битовые сдвиги (с примерами)

Операторы побитового и битового сдвига используются только для двух целочисленных типов ( Int и Long ) для выполнения операций на битовом уровне.

Для выполнения этих операций Kotlin предоставляет 7 функций, использующих инфиксную нотацию.


1. или

Функция или сравнивает соответствующие биты двух значений. Если один из битов равен 1, он дает 1. Если нет, он дает 0. Например,

12 = 00001100 (в двоичном формате)
25 = 00011001 (в двоичном формате)

Побитовое ИЛИ для 12 и 25
   00001100 или
   00011001
   ________
   00011101 = 29 (в десятичной системе) 

Пример: побитовое или операция

  fun main (args: Array ) {

    значение number1 = 12
    значение number2 = 25
    результат val: Int

    результат = число1 или число2 // результат = число1.или (число2)
    println (результат)
}  

Когда вы запустите программу, вывод будет:

29 

2. и

Функция и сравнивает соответствующие биты двух значений. Если оба бита равны 1, он оценивается как 1. Если любой из битов равен 0, он оценивается как 0. Например,

12 = 00001100 (в двоичном формате)
25 = 00011001 (в двоичном формате)

Битовая операция 12 и 25
   00001100 и
   00011001
   ________
   00001000 = 8 (в десятичной системе) 

Пример: побитовое и операция

  fun main (args: Array ) {

    значение number1 = 12
    значение number2 = 25
    результат val: Int

    результат = число1 и число2 // результат = число1.и (число2)
    println (результат)
}  

Когда вы запустите программу, вывод будет:

  8  

3. xor

Функция xor сравнивает соответствующие биты двух значений. Если соответствующие биты различны, он дает 1. Если соответствующие биты одинаковы, он дает 0. Например,

12 = 00001100 (в двоичном формате)
25 = 00011001 (в двоичном формате)

Побитовое ИЛИ для 12 и 25
   00001100 xor
   00011001
   ________
   00010101 = 21 (в десятичной системе) 

Пример: побитовая операция xor

  fun main (args: Array ) {

    значение number1 = 12
    значение number2 = 25
    результат val: Int

    result = number1 xor number2 // результат = число1.xor (число2)
    println (результат)
}  

Когда вы запустите программу, вывод будет:

21 

4. inv ()

Функция inv () инвертирует битовый шаблон. Делает каждые 0 до 1 и каждые 1 до 0.

35 = 00100011 (в двоичном формате)

Побитовое дополнение Операция 35
  00100011
  ________
  11011100 = 220 (в десятичной системе) 

Пример: Побитовое дополнение

  fun main (args: Array ) {

    val number = 35
    результат val: Int

    результат = число.inv ()
    println (результат)
}  

Когда вы запустите программу, вывод будет:

  -36  

Почему мы получаем на выходе -36 вместо 220 ?

Это потому, что компилятор показывает двойное дополнение этого числа; отрицательная запись двоичного числа.

Для любого целого числа n , дополнение до 2 для n будет - (n + 1) .

 Дополнение Decimal Binary 2
--------- --------- -------------------------------- -------
0 00000000 - (11111111 + 1) = -00000000 = -0 (десятичный)
1 00000001 - (11111110 + 1) = -11111111 = -256 (десятичный)
12 00001100 - (11110011 + 1) = -11110100 = -244 (десятичное)
220 11011100 - (00100011 + 1) = -00100100 = -36 (десятичный)

Примечание. Переполнение игнорируется при вычислении дополнения до 2.

Поразрядное дополнение до 35 равно 220 (в десятичной системе). Дополнение 2 до 220 равно -36. Следовательно, на выходе будет -36 вместо 220.


5. shl

Функция shl сдвигает битовую комбинацию влево на определенное количество указанных битов, и нулевые биты сдвигаются в младшие позиции.

212 (в двоичном формате: 11010100)

212 shl 1 оценивается как 424 (в двоичной системе: 110101000)
212 shl 0 оценивается как 212 (в двоичном формате: 11010100)
212 shl 4 оценивается как 3392 (в двоичном формате: 110101000000) 

Пример: побитовый сдвиг влево

  fun main (args: Array ) {
    число val = 212

    println (номер shl 1)
    println (число shl 0)
    println (номер shl 4)
}  

Когда вы запустите программу, вывод будет:

  424
212
3392  

6.shr

Функция shr сдвигает батарею битов вправо на определенное количество указанных битов.

212 (в двоичном формате: 11010100)

212 shr 1 оценивается как 106 (в двоичной системе: 01101010)
212 shr 0 оценивается как 212 (в двоичной системе: 11010100)
212 shr 8 оценивается как 0 (в двоичном формате: 00000000) 

Если число представляет собой знаковое число с дополнением до 2, знаковый бит сдвигается в старшие позиции.

  fun main (args: Array ) {
    число val = 212

    println (номер shr 1)
    println (номер shr 0)
    println (номер shr 8)
}  

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

  106
212
0  

7.ushr

Функция ushr сдвигает ноль в крайнее левое положение.


Пример: сдвиг вправо со знаком и без знака

  fun main (args: Array ) {
    значение number1 = 5
    значение число2 = -5

    // Подписанный сдвиг вправо
    println (number1 shr 1)

    // Беззнаковый сдвиг вправо
    println (номер1 ushr 1)

    // Подписанный сдвиг вправо
    println (number2 shr 1)

    // Беззнаковый сдвиг вправо
    println (number2 ushr 1)
}  

Когда вы запустите программу, вывод будет:

  2
2
-3
2147483645  

Обратите внимание, как функция сдвига вправо со знаком и без знака работает по-разному для дополнения до 2.

Дополнение до 2 в 2147483645 равно 3 .

.

Побитовые операторы - Справка разработчика

Переключить навигацию

  • Инструменты разработки
    • Какие инструменты мне нужны?
    • Программные средства
      • Начни здесь
      • MPLAB® X IDE
        • Начни здесь
        • Установка
        • Введение в среду разработки MPLAB X
        • Переход на MPLAB X IDE
          • Переход с MPLAB IDE v8
          • Переход с Atmel Studio
        • Конфигурация
        • Плагины
        • Пользовательский интерфейс
        • Проектов
        • файлов
        • Редактор
          • Редактор
          • Интерфейс и ярлыки
          • Основные задачи
          • Внешний вид
          • Динамическая обратная связь
          • Навигация
          • Поиск, замена и рефакторинг
          • Инструменты повышения производительности
            • Инструменты повышения производительности
            • Автоматическое форматирование кода
            • Список задач
            • Сравнение файлов (разница)
            • Создать документацию
        • Управление окнами
        • Сочетания клавиш
        • Отладка
        • Контроль версий
        • Автоматизация
          • Язык управления стимулами (SCL)
          • Отладчик командной строки (MDB)
          • Создание сценариев IDE с помощью Groovy
        • Поиск и устранение неисправностей
        • Работа вне MPLAB X IDE
        • Прочие ресурсы
      • Улучшенная версия MPLAB Xpress
      • MPLAB Xpress
      • MPLAB IPE
      • Программирование на C
      • Компиляторы MPLAB® XC
        • Начни здесь
        • Компилятор MPLAB® XC8
        • Компилятор MPLAB XC16
        • Компилятор MPLAB XC32
        • Компилятор MPLAB XC32 ++
        • Охват кода

        • MPLAB
      • Компилятор IAR C / C ++
      • Конфигуратор кода MPLAB (MCC)
      • Гармония MPLAB v2
      • Гармония MPLAB v3
      • среда разработки Atmel® Studio
      • Atmel СТАРТ (ASF4)
      • Advanced Software Framework v3 (ASF3)
        • Начни здесь
        • ASF3 Учебники
          • ASF Audio Sine Tone Учебное пособие
          • Интерфейс ЖК-дисплея с SAM L22 MCU Учебное пособие
      • Блоки устройств MPLAB® для Simulink®
      • Утилиты
      • Инструменты проектирования

      • FPGA
      • Аналоговый симулятор MPLAB® Mindi ™
    • Аппаратные средства
      • Начни здесь
      • Сравнение аппаратных средств
      • Средства отладки и память устройства
      • Исполнительный отладчик
      • Демо-платы и стартовые наборы
      • Внутрисхемный эмулятор MPLAB® REAL ICE ™
      • Эмулятор SAM-ICE JTAG
      • Внутрисхемный эмулятор

      • Atmel® ICE
      • Power Debugger
      • Внутрисхемный отладчик MPLAB® ICD 3
      • Внутрисхемный отладчик MPLAB® ICD 4
      • Внутрисхемный отладчик

      • PICkit ™ 3
      • Внутрисхемный отладчик MPLAB® PICkit ™ 4
      • MPLAB® Snap
      • MPLAB PM3 Универсальный программатор устройств
      • Принадлежности
        • Заголовки эмуляции и пакеты расширения эмуляции
        • Пакеты расширения процессора и отладочные заголовки
          • Начни здесь
          • Обзор

          • PEP и отладочных заголовков
          • Требуемый список заголовков отладки
            • Таблица обязательных отладочных заголовков
            • AC162050, AC162058
            • AC162052, AC162055, AC162056, AC162057
            • AC162053, AC162054
            • AC162059, AC162070, AC162096
            • AC162060
            • AC162061
            • AC162066
            • AC162083
            • AC244023, AC244024
            • AC244028
            • AC244045
            • AC244051, AC244052, AC244061
            • AC244062
          • Необязательный список заголовков отладки
            • Дополнительный список заголовков отладки - устройства PIC12 / 16
            • Дополнительный список заголовков отладки - устройства PIC18
            • Дополнительный список заголовков отладки - Устройства PIC24
          • Целевые следы заголовка отладки
          • Отладочные подключения заголовков
      • SEGGER J-Link
      • K2L Сетевые инструментальные решения
      • Рекомендации по проектированию средств разработки
      • Ограничения отладки - микроконтроллеры PIC
      • Инженерно-технические примечания (ETN) [[li]] Встраиваемые платформы chipKIT ™
  • Проектов
    • Начни здесь
    • Преобразование мощности
      • AN2039 Четырехканальный секвенсор питания PIC16F1XXX
    • 8-битные микроконтроллеры PIC®
    • 8-битные микроконтроллеры AVR®
    • 16-битные микроконтроллеры PIC®
    • 32-битные микроконтроллеры SAM
    • 32-разрядные микропроцессоры SAM
      • Разработка приложений SAM MPU с MPLAB X IDE
      • Примеры пакетов программного обеспечения

      • SAM MPU
    • Запланировано дополнительное содержание...
  • Продукты
    • 8-битные микроконтроллеры PIC
    • 8-битные микроконтроллеры AVR
      • Начни здесь
      • Структура 8-битного микроконтроллера AVR®

      • 8-битные периферийные устройства AVR®
        • Осциллятор
        • USART
        • прерываний
        • аналоговый компаратор и опорное напряжение
        • Таймер / счетчики
        • Внутренний датчик температуры
        • Работа с низким энергопотреблением
        • Сброс источников
      • Начало работы с микроконтроллерами AVR®
      • Использование микроконтроллеров AVR® с Atmel START
      • Запланировано дополнительное содержание...
    • 16-битные микроконтроллеры PIC и dsPIC DSC
    • 32-битные микроконтроллеры

.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *