Побитовые операторы и операторы сдвига (справочник по 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#: