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

Побитовые логические операции (`&`, `|`)

Данные операции могут использоваться при работе с портами ввода/вывода, например:

Мы имеем порт ввода/вывода или регистр с определенным значением в нем. Нам необходимо включить устройство управляемое первым битом, установив первый бит в 1. После нам потребуется выключить устройство, сбросив первый бит в 0.

1 1 1 1 0 0 0 0 - начальное значение порта ввода/вывода.

7 6 5 4 3 2 1 0 - нумерация битов управления устройствами.

Для реализации данной задачи нужно использовать маску включения и выключения устройства и использовать побитовые логические операции AND (&) и OR (|), ведь изменение состояния других подключенных устройств недопустимо!

Маска для включения устройства управляемого первым битом: 0000 0010 = 0x02

Маска для выключения устройств управляемого первым битом: 1111 1101 = 0xFD

Для безопасного включения устройства нужно использовать операцию побитовое ИЛИ, а для включения – побитовое И.

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

static void Main()
{
    byte port = 0xF0;    // 1111 0000  -  начальное значение порта ввода/вывода.
    byte mask = 0x02;  // 0000 0010  -  маска включения устройства управляемого первым битом.
    Console.WriteLine("port = {0:X}", port); // ситуация с лампочкой в комнате

    port = (byte)(port | mask);  // Включить устройство управляемое первым битом.
    Console.WriteLine("port = {0:X}", port);
    
    mask = 0xFD;   // 1111 1101  -  Создаем маску выключения устройства управляемого первым битом. 
    
    port = (byte)(port & mask);  // Выключить устройство управляемое первым битом.
    Console.WriteLine("port = {0:X}", port);

    // Delay.
    Console.ReadKey();
}

23

Побитовая логическая операция XOR (исключающее ИЛИ, ^)

Используя операцию XOR, можно зашифровать сообщение. В таком виде шифрования используется один ключ, как для шифрования, так и для расшифровки. Криптостойкость такого ключа, можно увеличить, если увеличить его длину.

Пример шифрования буквы 'A' используя ключ 0x0088:

static void Main(string[] args)
{
    ushort secretKey = 0x0088; // Секретный ключ (длина - 16 bit).
    char character = 'A';      // Исходный символ для шифрования.

    Console.WriteLine("Исходный символ: {0}, его код в кодовой таблице: {1:X}", character, (byte)character);
    Console.WriteLine("Размер символа: {0} = {1} бит", character, sizeof(char) * 8);

    // Зашифровываем символ.
    character = (char)(character ^ secretKey);
    Console.WriteLine("Зашифрованный символ: {0}, его код в кодовой таблице: {1:X}", character, (byte)character);

    // Расшифровываем символ.
    character = (char)(character ^ secretKey);
    Console.WriteLine("Расшифрованный символ: {0}, его код в кодовой таблице: {1:X}", character, (byte)character);

    // Delay.
    Console.ReadKey();
}

24

При необходимости данный вариант шифрования можно применить к каждой букве в текстовом файле.

Побитовая логическая операция NOT (отрицание, `~`)

Данная логическая операция используется при изменении знака двоичного числа.

Пример кода реализующего изменение знака числа записанного в переменной operand:

static void Main()
{
    int operand = 0x01;           // [0000 0001]
    int result = ~operand;        // [1111 1110]
    result++;                     // [1111 1111]

    Console.WriteLine(" ~ {0} + 1 = {1} ", operand, result);
    
    // Delay.
    Console.ReadKey();
}

25

Битовые логические сдвиги

Иногда случаются ситуации, когда значения определённого/-ых битов описывает различные ситуации, характеристики. Примером такой ситуации является возвращаемое значения свойства Tier класса RenderCapability у WPF приложениях.

RenderCapability - Позволяет WPF приложениям запрашивать текущий уровень отрисовки.

RenderCapability.Tier - Получает значение, указывающее уровень отрисовки текущего потока.

Тип возвращаемого значения свойства Tierint, а в значении 16 и 17 биты отвечают за уровень отрисовки текущего потока.

Возвращаемое || Уровень      ||  Примечания
значение     || визуализации || 
--------------------------------------------------------------------------------------------
0x00000000   || 0            || Для приложения на этом устройстве аппаратное ускорение недоступно.
0x00010000   || 1            || Для данной видеокарты доступно частичное графическое аппаратное ускорение.
             ||              || Это соответствует версииDirectX выше или равной 7.0, но меньше 9.0.
0x00020000   || 2            || Отрисовка уровня 2 означает, что большая часть графических 
             ||              || возможностей WPF должна использовать аппаратное ускорение 
             ||              || при условии, что необходимые системные ресурсы не исчерпаны.
             ||              || Это соответствует DirectX версии, которая больше или равна 9.0.

Подробнее о том, какие возможности WPF снабжены аппаратным ускорением на перечисленных выше уровнях, смотрите Graphics Rendering Tiers - WPF .NET Framework | Microsoft Docs

Также это число имеет следующие особенности:

  1. биты от 0 до 15 могут иметь значения
  2. биты от 18 до 31 – всегда 0 (поэтому для получения значений 16 и 17 битов использовать сдвиг влево в данном случае ненужно)

Пример получения значения, описывающие уровень визуализации:

tbResult.Text = "УРОВЕНЬ ВИЗУАЛИЗАЦИИ:\n";	// tbResult – название Label в интерфейсе

int renderingTier = RenderCapability.Tier >> 16;

if (renderingTier == 0)
    tbResult.Text += "Видеокарта не предоставляет аппаратного ускорения.";

if (renderingTier == 1)
    tbResult.Text += "Видеокарта предоставляет частичное аппаратное ускорение.";

if (renderingTier == 2)
    tbResult.Text += "Видеокарта предоставляет полное аппаратное ускорение.";

image

Источник: видеоурок Александра Шевчука "ВИДЕОУРОК №5. ЛОГИЧЕСКИЕ ОПЕРАЦИИ".

%D1%81%D1%82%D1%80%D0%B5%D0%BB%D0%BA%D0%B0%20%D0%B2%D0%BB%D0%B5%D0%B2%D0%BE%202 предыдущая статья | следующая статья %D1%81%D1%82%D1%80%D0%B5%D0%BB%D0%BA%D0%B0%20%D0%B2%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%202