Битовые операции, часть Инверсия и сдвиг


& 0 это то же, что 0 * 0. Результат 0. Результат 1 возможен только тогда, когда и


Download 30.19 Kb.
bet4/4
Sana13.04.2023
Hajmi30.19 Kb.
#1350169
1   2   3   4
Bog'liq
Битовые операции, часть 1. Инверсия и сдвиг. Битовые операции, часть 2.

0 & 0 это то же, что 0 * 0. Результат 0.
Результат 1 возможен только тогда, когда и первая часть выражения, и вторая часть выражения равны 1. Отсюда и название "и". Давайте посмотрим на примере реальных чисел:

Чем полезна такая операция?
Если у вас хранится какое-то число, то операция "и" позволяет получить избранные биты из этого числа, отбросив все остальные. Для этого нужно создать битовую маску, в которой нужно поставить 1 там, где вы хотите сохранить бит, и 0 там, где нужно отбросить. Но зачем получать избранные биты из числа?
У вас может быть несколько условий, задающих текущее состояние программы. Если речь об игре, то можно сделать такие состояния игрока:

  1. Игрок жив

  2. Игрок отравлен

  3. Игрок поражен слепотой

  4. Игрок усилен

  5. ...

Состояния могут наступать одновременно. Например, игрок одновременно жив, отравлен и усилен. Вы можете хранить каждое такое состояние в отдельной переменной. И проверять их так же по отдельности. Но можно записать все состояния в одну переменную с помощью битов.

Как проверить, отравлен ли игрок? Нужно взять переменную, где хранится его состояние (00001011) и провести операцию "и" с числом 00000010 (2). Такое число называется маской. В маске стоит единственная единица на том месте, где хранится бит "отравлен". После операции "и" с такой маской все биты будут обнулены, а бит "отравлен" останется таким, как был. Если он 1 – полученный результат будет не равен нулю.
if (status & 2 != 0) { ... игрок отравлен ... }
Если мы хотим узнать, есть ли у игрока вообще какие-либо изменения состояния, мы можем написать маску сразу для всех: 00001110 (14). Если игрок находится хоть в одном из измененных состояний, мы получим ненулевой результат.
if (status & 14 != 0) { ... у игрока изменено состояние ... }
Получать избранные биты также полезно в следующих случаях:

  • Взять остаток от деления на 2, 4, 8, 16, 32, 64, 128 и т.д. Нужна маска, в которой все биты равны 0, кроме нескольких младших бит. Если нужен остаток от деления на 2, то это маска 1. Если остаток от деления на 4, то маска 11 (3). Если от деления на 8, то маска 111 (7), Если от деления на 16, то маска 1111 (15). Заметим, что маска на 1 меньше, чем число, на которое делим. Давайте проверим: остаток от 5/4 это 5 & 3, то есть 101 & 011 = 001, то есть 1.

  • Взять только младший байт числа: нужна маска, у которой все нули, кроме 8 младших бит: 0000000011111111 (255). После операции с такой маской "в живых останутся" только младшие 8 бит, или младший байт. Взятие младшего байта числа (a & 255) равносильно взятию остатка от деления на 256.

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

Избранные биты можно не только сохранять, но и наоборот стирать. Например, если у игрока прошло состояние слепоты, нужно обнулить в статусе тот бит, который отвечает за слепоту. Для этого мы берем маску для бита слепоты 00000100 (4) и инвертируем её (~4), получая 11111011. После операции "и" с такой маской в статусе останутся все биты, которые были, а бит слепоты станет 0.
status = status & ~4
Мы можем превратить нечетное число в четное, обнулив его младший бит (он же остаток от деления на 2). Для этого нужна маска, у которой все биты установлены в 1, кроме младшего. Такая маска обнулит младший бит и сохранит остальные биты числа.
5 & ~1 = 4
Вот пока основная суть битовых операций. Остались ещё операции "или" и "исключающее или", о них будет в следующем выпуске.
Download 30.19 Kb.

Do'stlaringiz bilan baham:
1   2   3   4




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling