Побитовые операторы и операторы сдвига (справочник по C#)

Побитовые операторы и операторы сдвига (справочник по C#)

Следующие операторы выполняют побитовые операции или операции сдвига с операндами целочисленных или символьных типов:

  • Унарный оператор (побитовое дополнение)
  • Бинарные операторы сдвига (сдвиг влево) и (сдвиг вправо)
  • Бинарные операторы (логическое и), (логическое или) и (логическое исключающее или)

Эти операторы определены для типов int , uint , long и ulong . Если оба операнда имеют другие целочисленные типы ( sbyte , byte , short , ushort или char ), их значения преобразуются в тип int , который также является типом результата операции. Если операнды имеют разные целочисленные типы, их значения преобразуются в ближайший содержащий целочисленный тип. Дополнительные сведения см. в разделе Числовые повышения уровня в статье Спецификации языка C#.

Операторы & , | и ^ также определены для операндов типа bool . Дополнительные сведения см. в разделе Логические операторы.

Побитовые операции и операции сдвига никогда не вызывают переполнение и дают одинаковые результаты в проверенных и непроверенных контекстах.

Оператор побитового дополнения

создает побитовое дополнение своего операнда путем инвертирования каждого бита:

Можно также использовать символ

для объявления методов завершения. Дополнительные сведения см. в разделе Методы завершения.

Оператор сдвига влево <<

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

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

Поскольку операторы сдвига определены только для типов int , uint , long и ulong , результат операции всегда содержит по крайней мере 32 бита. Если левый операнд имеет другой целочисленный тип ( sbyte , byte , short , ushort или char ), его значение преобразуется в тип int , как показано в следующем примере:

Оператор сдвига вправо >>

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

Операция сдвига вправо удаляет младшие разряды, как показано в следующем примере:

Позиции пустых битов высокого порядка задаются с учетом типа левого операнда следующим образом:

Если левый операнд имеет тип int или long , оператор сдвига вправо выполняет int сдвиг: значение наиболее значимого бита (бит знака) левого операнда передается в позиции пустого битового индекса с высоким порядковым значением. То есть для пустых битовых позиций высокого порядка задается ноль, если левый операнд неотрицательный, и единица, если он отрицательный.

Если левый операнд имеет тип uint или ulong , то оператор сдвига вправо выполняет uint смену: позиции пустых битов высокого порядка всегда устанавливаются в ноль.

Оператор логического И &

Оператор & вычисляет побитовое логическое И целочисленных операндов:

Для bool операндов & оператор выдает bool из своих операндов. Унарный & оператор является & .

Оператор логического исключения ИЛИ ^

Оператор ^ вычисляет побитовое логическое исключающее ИЛИ, также известное как побитовое логическое XOR, своих целочисленных операндов:

Для bool операндов ^ оператор рассчитывает bool для своих операндов.

Оператор логического ИЛИ |

Оператор | вычисляет побитовое логическое ИЛИ своих целочисленных операндов:

Для bool операндов | оператор выдает bool для его операндов.

Составное присваивание

Для бинарного оператора op выражение составного присваивания в форме

за исключением того, что x вычисляется только один раз.

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

Из-за восходящих приведений результат операции может быть невозможно неявно преобразовать в тип T из x . В этом случае, если op является предопределенным оператором, и результат операции является явно преобразуемым в тип T x , выражение составного присваивания формы x op= y эквивалентно x = (T)(x op y) , за исключением того, что x вычисляется только один раз. В следующем примере продемонстрировано такое поведение.

Приоритет операторов

Следующий список упорядочивает побитовые операторы и операторы сдвига по приоритету, от высокого до низкого:

    Оператор побитового дополнения

Порядок вычисления, определяемый приоритетом операторов, можно изменить с помощью скобок ( () ).

Полный список операторов C#, упорядоченный по уровню приоритета, можно найти в разделе Приоритет операторов статьи Операторы C#.

Величина смещения операторов сдвига

Для операторов << сдвига и >> тип правого операнда должен быть int или типа с << в int .

Для выражений x << count и x >> count фактическая величина сдвига зависит от типа x следующим образом:

Если тип x имеет значение int или uint , то счетчик сдвигов определяется младшими x битами правого операнда. То есть величина сдвига вычисляется на основе count & 0x1F (или count & 0b_1_1111 ).

Если тип x имеет значение long или ulong , то счетчик сдвигов определяется младшими x битами правого операнда. То есть величина сдвига вычисляется на основе count & 0x3F (или count & 0b_11_1111 ).

В следующем примере продемонстрировано такое поведение.

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

Логические операторы перечисления

Операторы, & , | и ^ также поддерживаются любым типом

. Для операндов одного типа перечисления логическая операция выполняется по соответствующим значениям базового целочисленного типа. Например, для любого x и y типа перечисления T с базовым типом U выражение x & y дает тот же результат, что и выражение (T)((U)x & (U)y) .

Побитовые логические операторы обычно используются с типом перечисления, который определяется с помощью атрибута Flags. Дополнительные сведения см. в разделе Типы перечислений как битовые флаги в статье Типы перечислений.

Возможность перегрузки оператора

Определяемый пользователем тип может перегружать операторы, << >> ,, & | , и ^ . При перегрузке бинарного оператора соответствующий оператор составного присваивания также неявно перегружается. Определяемый пользователем тип не может перегружать оператор составного присваивания явным образом.

Если определяемый пользователем тип T перегружает оператор << или >> , тип левого операнда должен быть T , а тип правого — int .

Спецификация языка C#

Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:

📎📎📎📎📎📎📎📎📎📎