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

78

В C# предусмотрен ряд поразрядных операторов, расширяющих круг задач, для решения которых можно применять C#. Поразрядные операторы воздействуют на отдельные двоичные разряды (биты) своих операндов. Они определены только для целочисленных операндов, поэтому их нельзя применять к данным типа bool, float или double.

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

Поразрядные операторы C#
Оператор Значение
& Поразрядное И
| Поразрядное ИЛИ
^ Порязрядное исключающее ИЛИ
<< Сдвиг влево
>> Сдвиг вправо
~ Дополнение до 1 (унарный оператор НЕ)

Поразрядные операторы И, ИЛИ, исключающее ИЛИ и НЕ

Поразрядные операторы И, ИЛИ, исключающее ИЛИ и НЕ обозначаются следующим образом: &, |, ^ и ~. Они выполняют те же функции, что и их логические аналоги. Но в отличие от логических операторов, поразрядные операторы действуют на уровне отдельных двоичных разрядов.

С точки зрения наиболее распространенного применения поразрядную операцию И можно рассматривать как способ подавления отдельных двоичных разрядов. Это означает, что если какой-нибудь бит в любом из операндов равен 0, то соответствующий бит результата будет сброшен в 0. Поразрядный оператор ИЛИ может быть использован для установки отдельных двоичных разрядов. Если в 1 установлен какой-нибудь бит в любом из операндов этого оператора, то в 1 будет установлен и соответствующий бит в другом операнде. Поразрядный оператор исключающее ИЛИ устанавливает двоичный разряд операнда в том и только в том случае, если двоичные разряды сравниваемых операндов оказываются разными, как в приведенном ниже примере. Для понимания вышесказaнного, разберите следующий пример:

Применение поразрядных операторов

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            chet(16);
            provChet(8);
            nechet(16);

            Console.ReadLine();
        }

        // Метод, преобразующий все нечетные числа в четные
        // в диапазоне [0, x] c помощью 
        // поразрядного оператора &
        static void chet(int x)
        {
            int result;
            Console.WriteLine("Преобразованный диапазон чисел от 0 до {0}:\n",x);
            for (int i = 0; i <= x; i++)
            {
                // Сбрасываем младший разряд числа, чтобы
                // получить четное число
                result = i & 0xFFFE;
                Console.Write("{0}\t",result);
            }
        }

        // Метод, проверяющий является ли число четным
        static void provChet(int x)
        {
            Console.WriteLine("\n\nПроверка четности чисел в диапазоне от 1 до {0}\n",x);
            for (int i = 1; i <= x; i++)
            {
                if ((i & 1) == 0)
                    Console.WriteLine("Число {0} - является четным",i); 
                else
                    Console.WriteLine("Число {0} - является нечетным",i);
            }
        }

        // Метод, преобразующий четные числа в нечетные
        // с помощью поразрядного оператора |
        static void nechet(int x)
        {
            int result;
            Console.WriteLine("\nПреобразованный диапазон чисел от 0 до {0}:\n",x);
            for (int i = 0; i <= x; i++)
            {
                result = i | 1;
                Console.Write("{0}\t",result);
            }
        }

    }
}

Применение поразрядных операторов

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

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

      значение << число_битов
      значение >> число битов

где число_битов — это число двоичных разрядов, на которое сдвигается указанное значение.

При сдвиге влево все двоичные разряды в указываемом значении сдвигаются на одну позицию влево, а младший разряд сбрасывается в нуль. При сдвиге вправо все двоичные разряды в указываемом значении сдвигаются на одну позицию вправо. Если вправо сдвигается целое значение без знака, то старший разряд сбрасывается в нуль. А если вправо сдвигается целое значение со знаком, то разряд знака сохраняется. Напомним, что для представления отрицательных чисел старший разряд целого числа устанавливается в 1. Так, если сдвигаемое значение является отрицательным, то при каждом сдвиге вправо старший разряд числа устанавливается в 1. А если сдвигаемое значение является положительным, то при каждом сдвиге вправо старший разряд числа сбрасывается в нуль.

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            byte n = 6, result;

            // Умножить на 2
            result = (byte)(n << 1);
            Console.WriteLine("{0} * 2 = {1}",n,result);

            // Умножить на 4
            result = (byte)(n << 2);
            Console.WriteLine("{0} * 4 = {1}",n,result);

            // Разделить на 2
            result = (byte)(n >> 1);
            Console.WriteLine("{0} / 2 = {1}",n,result);

            Console.ReadLine();
        }
    }
}
Применение операторов сдвига
Пройди тесты
Лучший чат для C# программистов