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

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

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

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

Все доступные в C# поразрядные операторы приведены ниже:

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

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

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

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

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

Поразрядный оператор Исключающее ИЛИ устанавливает двоичный разряд операнда в том и только в том случае, если двоичные разряды сравниваемых операндов оказываются разными, как в приведенном ниже примере.

Унарный оператор НЕ заменяет в каждом разряде 1 на 0, а 0 на 1.

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

  1101 0011    1101 0011    1101 0011
  1001 1001    1001 1001    1001 1001    1101 0011
 &---------   |---------   ^---------   ~---------
  1001 0001    1101 1011    0100 1010    0010 1100

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

using System;
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);
           }
        }
    }
}

Результат:
2131

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

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

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

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

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

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

Рассмотрим пример:

using System;
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(); 
      }
   }
}

Результат:
2132
Рассмотрим далее достаточно замысловатый тернарный (тройной) оператор, заимствованный еще из языка С, или точнее — из Алгола 60.


NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.


Понравилась статья? Поделиться с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о

5 комментариев
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

что мне нужно подучить что бы понять что тут происходит?
// Сбрасываем младший разряд числа,
// чтобы получить четное число
result = i & 0xFFFE;<—— что это?
Console.Write("{0}\t", result);
и что происходит тут?
/ Сбрасываем младший разряд числа,
/if ((i & 1) == 0)
Console.WriteLine("Число {0} — является четным", i);

В школе помню проходили логические операции и всякие трюки с двоичными и 16ми системами счисления, интересные были задачки)
Скажите, а как часто на практике в разработке прибегают к двоичным системам счислениям? Да и главное есть ли в этом какая-то реальная потребность или из-за привычки/удобства?

Пока не вспомнил представление десятичных чисел в двоичной системе,
не понимал о чем речь идет вообще.
А из примера ниже все понятно:
6 в двоичной системе это 110.
сдвигаем влево ряд с прибавлением 0 на конце получается 1100, а это
число 12 наше привычное.
далее если еще раз сдвинуть, будет 11000, это число 24.
другими словами, сдвиг влево это умножение на 2, сдвиг вправо это деление на 2.
Вроде так?

5
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x