Манипуляции с байтами и битами

Мы добрались до операторов, которые работают с двоичной логикой. Они пополнят вашу грамотность программиста и дадут возможность работать с числами на более низком уровне. Сразу приготовьтесь видеть в числах их двоичное представление.

 

XOR (исключающее ИЛИ)

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

Аргументы оператора Десятичное число Биты числа
левое число 10 1 0 1 0
правое число 12 1 1 0 0
результат 6 0 1 1 0

Как может использоваться этот оператор? Я например его использую как флаг для чередования 0 и 1. В моей игре ЧЕРЕПА , можете увидеть практическое применение. Кроме этого данный оператор широко используется при преобразовании бит в графике.

Пример:
Dim a As Integer = 1
For q As Integer = 1 To 10
    a = a Xor 1
    ? a
Next
Sleep

 

OR (ИЛИ)

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

Аргументы оператора Десятичное число Биты числа
левое число 10 1 0 1 0
правое число 12 1 1 0 0
результат 14 1 1 1 0

Данный оператор очень часто используется при объединении бит в параметрах функций. Я же вам покажу пример определения четности или нечетности числа

Пример:
Dim As Ubyte a=&b11111110 '254
For q As Ubyte = 1 To 10
    If (q Or a)<>&b11111111 Then '255
        ? q & "  Even"
    Else
        ? q & "  NO even"
    Endif
Next
Sleep


В этом примере создана маска с помощью числа 254 , которое в двоичном представлении равна &b11111110.  То есть мы установили все биты двоичного числа в единицу кроме последнего , ведь именно последний бит определяет четность числа.  Теперь при преобразовании оператором OR результат будет равен либо 254(четное) ,  либо 255(нечетное).

 

AND (И)

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

Аргументы оператора Десятичное число Биты числа
левое число 10 1 0 1 0
правое число 12 1 1 0 0
результат 8 1 0 0 0

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

Еще один пример проверки на четность числа:
Dim As Ubyte a=1
For q As Ubyte = 1 To 250
    If A And q Then
        ? q & "  NO even"
    Else
        ? q & "  Even"
    Endif
Next
Sleep

 

EQV (Эквивалент)

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

Аргументы оператора Десятичное число Биты числа
левое число 10 1 0 1 0
правое число 12 1 1 0 0
результат 8 1 0 0 1

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

Пример:
Dim As Ubyte a = &b00110011
Dim As Ubyte b = &b01010101, c
c = a Eqv b 'c = &b10011001

 

IMP (Импликация)

При преобразовании этим оператором нулевые биты будут возвращены, только если бит левого числа равен 1 , а правого 0  В остальных случаях оператор вернет единицы. Взгляните на таблицу:

Аргументы оператора Десятичное число Биты числа
левое число 10 1 0 1 0
правое число 12 1 1 0 0
результат 13 1 1 0 1

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

Пример:

Dim As Ubyte a = &b00110011
Dim As Ubyte b = &b01010101, c
c = a Imp b 'c = &b11011101

 

NOT (Отрицание)

Этот оператор нулевые биты числа делает единицами и наоборот. Взгляните на таблицу:

Аргументы оператора Десятичное число Биты числа
правое число 12 1 1 0 0
результат 3 0 0 1 1

Данный оператор можете посмотреть в практическом применении инверсии рисунка

Пример:

Dim As Ubyte a=&b00001111
? Bin(Cast(Ubyte,Not a))
Sleep 

 

SHL и SHR

Функции для сдвига бит в левую(shl) и правую сторону(shr) сторону. В прошлой статье мы с вами видели из таблицы, что если старший бит сдвинуть влево и приписать справа 0 , то число увеличивается вдвое (то есть степень двойки). Как раз для сдвига бит и предназначены операторы shl и shr. Оператор SHL работает в сотню раз быстрее чем стандартный оператор возведения в степень ^, поэтому если где-то нужна скорость, правильнее будет приспособить этот оператор.
При работе с оператором SHR есть некоторая хитрость. Этот оператор делает обратную операцию по отношению к SHL , однако если с правого края числа был единичный бит, он при сдвиге пропадает навсегда и в расчет не идет, в итоге обратная по отношению к SHL операция выполняется , но остаток пропадает.

Пример (SHL):

For a As Integer = 1 To 10
    ? 3 Shl a , Bin(3 Shl a)
Next
Sleep

Пример (SHR):

For a As Integer = 1 To 10
    ? 3000 Shr a , Bin(3000 Shr a)
Next
Sleep

 

LoByte

На 32-bit системе наш процессор состоит из 32х битных регистров. В каждый из этих регистров можно умещать только 32х битное число или 4 байта. Если число больше (как в случае с типом Longint на windows 32-bit), то оно раскидывается по двум регистрам. Конечно есть и большие вспомогательные регистры (сопроцессоры , в них помещается 80 битовые числа) , но скорость их значительно ниже основных регистров и работают они совершенно по другому принципу. Однако при работе с дробными числами, вычислениями корней и макросами они очень удобны и практичны.

Как вы наверно уже поняли 32х битное число представляет собой:

00000000 00000000 00000000 00000000

Как видите число делится на 4 байта или 32 бита. И каждый байт на 8 бит. С помощью различных макросов мы можем получить доступ к каждому биту числа, а так же просто к младшей и старшей половине (16 битам) и к младшей и старшей четвертинке половинки этого числа (8 битам). Как раз для получения значения младшего байта (розовый цвет) и предназначен макрос LoByte.

Пример:

Dim As Long A=&b11111111000000001111111111111111  
? Lobyte(A)
Sleep


Как вы могли заметить результат 255. Именно этому числу соответствует двоичное представление младшего байта 11111111

 

HiByte

Для получения старшего байта (синий цвет) существует макрос HiByte. Работает он так же, только получает другой байт числа.

Пример:

Dim As Long A=&b11111111000000000000111111111111  
? Hibyte(A)
Sleep


Результат 15 и понятно почему, ведь правда? 

 

LoWord и Hiword

Для получения младшей и старшей половины числа используются макросы LoWord и Hiword соответственно. Эти макросы мы уже использовали в статье про консоль.

Пример:

Dim As Long A=&b11111111000000001111111111111111  
? Loword(A)
? Hiword(A)
Sleep


Результат: 65535  и 65280

 

BIT

Для получения значения любого бита числа можно применить макрос BIT. Его синтаксис:

BIT ( число , номер бита в числе)

Отсчет идет с 0 до 31 бита. Если бит по данному номеру 1 , то возвращаемое значение -1 , если бит по данному номеру 0 , то возвращаемое значение 0.

Десятичное число Двоичное число Операция Результат
1 0001 Bit (1,0) -1
2 0010 Bit (2,0) 0
3 0011 Bit (3,1) -1
4 0100 Bit (4,2) -1
5 0101 Bit (5,1) 0
6 0110 Bit (6,3) 0

Красным показано, какой бит определяется функцией.

Пример (определение имеющихся дисков в системе):

#INCLUDE "windows.bi"
Dim As Integer DR= GetLogicalDrives
For a As Integer = 0 To 31
    If Bit(DR,a)=-1 Then
        ? Chr( 65+a)
    Endif
Next
Sleep


Я конечно немного залез вперед с функцией API (GetLogicalDrives) , но мне хотелось показать практическое применение макроса. По сути функция возвращает битовую маску имеющихся дисков в системе:

0 бит соответствует A
1 бит соответствует B
2 бит соответствует C
3 бит соответствует D
4 бит соответствует E
и так далее.

Макрос BIT определяет заполнение бита. Функцией CHR мы попросту выводим нужные буквы, которые соответствуют этим дискам.

 

BitSet и BitReSet

Для установки отдельному биту значения 1 или 0 , можно использовать макросы BitSet и BitReSet соответственно. Возвращаемое значение - преобразованное число с учетов установки бита.

Синтаксис:

значение = BitSet ( число , номер бита в числе)

значение = BitReSet ( число , номер бита в числе)

Пример:

Dim As Long A=&b1
? A
? Bitset(A,1)
? Bitreset(A,0)
Sleep


При использовании API функций Windows вы часто будете сталкиваться с отдельными байтами и битами числа. Если что-то непонятно в данной статье, пробуем прочитать и понять еще раз. Если и после этого возникнут трудности с понимаем , тогда спрашиваем на форуме
 
Всего доброго!

содержание | назад | вперед