Манипуляции с байтами и битами
Мы добрались до операторов, которые работают с двоичной логикой. Они пополнят вашу грамотность программиста и дадут возможность работать с числами на более низком уровне. Сразу приготовьтесь видеть в числах их двоичное представление.
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 вы часто будете сталкиваться с
отдельными байтами и битами числа. Если что-то непонятно в данной статье,
пробуем прочитать и понять еще раз. Если и после этого возникнут трудности с
понимаем , тогда спрашиваем на форуме
Всего доброго!
содержание | назад | вперед