Я знаю, что подобных статей на просторе интернета хватает, но я считаю что они не сильно помогают если читатель не знаком с информацией о битах более детально. В моей статье так же будут примеры использования битов в написании плагинов. Если какая-то информация из статьи окажется недостоверной, либо вы ее не поняли - сообщите мне в комментариях.
Что такое битовые поля (bit-fields)?
Битовое поле — в программировании число, занимающее некоторый набор битов, напрямую не адресуемый процессором ( не массив ). Число бит в битовом поле определяется количеством байтов выделенных на используемый тип данных. По умолчанию в битовом поле все биты равны 0. Когда в битовом поле не будет битов равных 1 - то значение битового поля в результате будет равно 0. Если один или более битов будут равны 1 в пределах битового поля, то получающееся число будет отличным от нуля. У AMX-X есть только один тип данных, который является 4-байтовой ячейкой, таким образом, это ограничено 32 битами в единственном битовом поле. Если Вы хотите управлять битами выше 32, см. пример массива битового поля ниже.
Пример бит полей:
1-bytes ( байт ) = 8 bits ( бит ) == 0000 0000
2-bytes ( байт ) = 16 bits ( бит ) = 0000 0000 0000 0000
4-bytes ( байт ) = 32 bits ( бит ) = 0000 0000 0000 0000 0000 0000 0000 0000
2-bytes ( байт ) = 16 bits ( бит ) = 0000 0000 0000 0000
4-bytes ( байт ) = 32 bits ( бит ) = 0000 0000 0000 0000 0000 0000 0000 0000
Как числа хранятся на компьютере?
Вся информация на компьютере храниться в памяти ( Оперативной ( RAM ), Диски ( ROM ), жестких дисках (HDD), флешках и так далее ). На самом низком уровне память состоит из on/off выключателей ( известных как биты ). Целое значение - результат комбинации битов и устанавливается к 1 или 0. Если Вы увидите, как я ссылаюсь на двоичное число, это подразумевает битовое представление целого числа.
Каждый бит соответствует 2 степени. Для примера я буду использовать восемь бит, что-бы показать как биты формируют число. Ниже биты будут упорядоточенны как 7654 3210 ( от семи до нуля = восемь ):
число 1 ....= это 2 в степени 0 == Запись в битах: 0000 0001
Число 2 ....= это 2 в степени 1 == Запись в битах: 0000 0010
Число 4 ....= это 2 в степени 2 == Запись в битах: 0000 0100
Число 8 ....= это 2 в степени 3 == Запись в битах: 0000 1000
Число 16 ..= это 2 в степени 4 == Запись в битах: 0001 0000
Число 32 ..= это 2 в степени 5 == Запись в битах: 0010 0000
Число 64 ..= это 2 в степени 6 == Запись в битах: 0100 0000
Число 128 = это 2 в степени 7 == Запись в битах: 1000 0000
Число 2 ....= это 2 в степени 1 == Запись в битах: 0000 0010
Число 4 ....= это 2 в степени 2 == Запись в битах: 0000 0100
Число 8 ....= это 2 в степени 3 == Запись в битах: 0000 1000
Число 16 ..= это 2 в степени 4 == Запись в битах: 0001 0000
Число 32 ..= это 2 в степени 5 == Запись в битах: 0010 0000
Число 64 ..= это 2 в степени 6 == Запись в битах: 0100 0000
Число 128 = это 2 в степени 7 == Запись в битах: 1000 0000
Для примера сохраним число 79 в битах:
Разделим 79 на 1 + 2 + 4 + 8 + 64 = 79
Эту запись можно представить в виде
2^0 + 2^1 + 2^2 + 2^3 + 2^6 = 79 . Теперь те степени которые мы используем в примере будут единичками, остальные 0. Запишем что получилось:
0100 1111 - это наше 79. ( Биты упорядоточенны как 7654 3210 )
Какие есть операторы и как они работают?
Побитовые логические операции
Побитовые логические операции
Оператор |:
Данный оператор работает как оператор || ( OR ), но производит операцию сравнения над каждым битом.
first_byte = "10010001"
second_byte = "01010001"
first_byte | second_byte = "11010001"
Другими словами, если оба соответствующих бита операндов равны 0, двоичный разряд результата равен 0; если же хотя бы один бит из пары равен 1, двоичный разряд результата равен 1.
| 1 0
1 1 1
0 1 0
Оператор &
Данный оператор работает, как логический оператор && ( AND ), но производит операцию над каждым битом.
first_byte = "10010001"
second_byte = "01010001"
first_byte & second_byte = "00010001"
Другими словами, если оба соответствующих бита операндов равны 1, результирующий двоичный разряд равен 1; если же хотя бы один бит из пары равен 0, результирующий двоичный разряд равен 0.
& 1 0
1 1 0
0 0 0
Оператор ^ (Исключающее ИЛИ - XOR)
Данный оператор работает, как логический оператор ^^, но производит операцию над каждым битом.
first_byte = "10010001"
second_byte = "01010001"
first_byte ^ second_byte = "11000000"
Другими словами, если соответствующие биты операндов различны, то двоичный разряд результата равен 1; если же биты совпадают, то двоичный разряд результата равен 0.
^ 1 0
1 0 1
0 1 0
Оператор ~
Данный оператор отрицает каждый бит, поэтому бит 0 становится 1, а бит 1 становится 0.
first_byte = "10010001"
~first_byte = "01101110"
Другими словами, на той позиции, где в двоичном представлении операнда был 0, в результате будет 1, и, наоборот, где была 1, там будет 0. Например:
~1 = 0
~0 = 1
Битовые сдвиги
К битовым операциям также относят битовые сдвиги. При сдвиге значения битов копируются в соседние по направлению сдвига. Различают несколько видов сдвигов — логический, арифметический и циклический, в зависимости от обработки крайних битов. В PAWN используется логический сдвиг.
При логическом сдвиге значение последнего бита по направлению сдвига теряется (копируясь в бит переноса), а первый приобретает нулевое значение.
Логические сдвиги влево и вправо используются для быстрого умножения и деления на 2, соответственно.
Логический сдвиг <<
Данный оператор смещает биты влево на указанное число позиций.
"00001100" << 1 = "00011000"
Если мы преобразуем полученное число в десятичную систему, то увидем, что в результате получилось число умноженное на 2. Следовательно, 1<<3 будет тоже самое, что 2^3 * 1.
Логический сдвиг >>
Данный оператор смещает биты вправо на указанное число позиций.
"00000111" >> 3 = "00000000"
1*(1^1) + 1*(2^2) + 1*(2^3) + 1*(2^6) = 2 + 4 + 8 + 64 битсумма равна 78
PS
нули не стал переводить так как смысла нет деление на ноль = нулю