„Здрасти, Амиго!“
„Също така бих искал да говоря за битовите маски и XOR.“
„Вече знаете, че числата се състоят от битове и можете да извършвате различни операции върху тези битове. Побитовата маска е представяне на няколко различни логически стойности (истински/фалшиви стойности) като едно цяло число. В този случай всяка булева стойност съответства на конкретен бит. Ето How може да се направи това:"
„Двоичното представяне на степени на две (1, 2, 4, 8, 16, 32, ...) включва само задаване на един бит:“
Номер | Двоично представяне |
---|---|
1 | 0000 0001 |
2 | 0000 0010 |
4 | 0000 0100 |
8 | 0000 1000 |
16 | 0001 0000 |
19 (не е степен на две) | 0001 0011 |
31 (не е степен на две) | 0001 1111 |
„Така че всяко цяло число може да се третира като масив от битове or масив от булеви стойности.“
„Ето How можете да съхранявате различни булеви стойности в едно число:“
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
int result = 0;
if (a) result += 1; // 1 == 20 — bit 0
if (b) result += 2; // 2 == 21 — bit 1
if (c) result += 4; // 4 == 22 — bit 2
if (d) result += 8; // 8 == 23 — bit 3
"Сега всеки бит е 1, ако съответната булева променлива е вярна."
В нашия случай променливите a и c бяха верни, така че резултатът е equals на 1+4 == 5
0000 0101
0000 dcba
— Мисля, че знам Howво се случва.
— Е, щом разбираш, да продължим.
"Int има 32 бита. Един от тях се използва за знак на числото, а останалите 31 могат да се използват за съхраняване на стойностите на 31 булеви променливи."
„Дългият има 64 бита, където можем да съхраняваме 63 булеви променливи.“
— Да.
„Десетки променливи, натъпкани в едно число. Това са доста.“
— Но къде се прилага това?
"Основно в ситуации, в които трябва да съхранявате много информация за обекти. Когато съхранявате много информация за обект, винаги има няколко дузини булеви променливи. "С този подход всички те се съхраняват удобно в едно число ."
„С ударение върху думата „съхранен“. Защото всъщност използването на номера не е толкова удобно.“
"Между другото, точно това исках да попитам. Как да извлечем булевата стойност от числото?"
„Изобщо не е сложно. Да кажем, че трябва да определите дали бит 6 е зададен на 1 (2 на степен пет е 32). Можем да проверим така:“
int a = 32; // 25 == 0010 0000
int b = 8; // 23 == 0000 1000
int c = 2; // 21 == 0000 0010
int result = a + b + c; // 32 + 8 + 2 == 42 == 0010 1010
int a = result & 32; // 0010 1010 & 0010 0000 = 0010 0000
int b = result & 8; // 0010 1010 & 0000 1000 = 0000 1000
int c = result & 2; // 0010 1010 & 0000 0010 = 0000 0010
„По този начин работата с битови маски включва три операции:“
1) Задайте конкретен бит на 0
2) Задайте конкретен бит на 1
3) Проверете стойността на конкретния бит.
„Вземете например бит 6.“
„Как да зададете бит 6 на 1?“
Код | Описание |
---|---|
|
Как се настройва бит 6 на 1? |
|
Как се настройва бит 6 на 0? |
|
Как получавате стойността на бит 6? |
„Това е много необичайно, но не е трудно. Човече, сега съм горещ програмист.“
„И още един малък съвет How лесно да получите числа със специфичен бит, зададен на 0 or 1: 01000000 or 10111111.“
За това имаме операторите >> и << .
"1 е 2 на нулева степен. С други думи, число с бит 0, зададен на 1. Нуждаем се от число с бит 6, зададен."
int c = 1 << 6; // 0000 0001 << 6 == 0100 0000 == 64
"Страхотно! Това наистина е полезно за такива случаи."
„Но Howво ще стане, ако имам нужда от число, при което всеки бит е зададен на 1, с изключение на един конкретен бит, който е зададен на 0?“
„Това също не е трудно:“
int d = ~(1 << 6); // ~0100 0000 == 10111111
"С други думи, всичко е много просто:"
Код | Описание |
---|---|
|
Как се настройва бит 6 на 1? |
|
Как се настройва бит 6 на 0? |
|
Как получавате стойността на бит 6? |
"Не изглежда много трудно. Но няма да го запомня веднага."
„Но ако срещнете страшен израз като „резултат &= ~(1 << 6)“ в codeа на някой друг, ще знаете, че този някой просто работи с битова маска.“
"И ако го срещате често, тогава той ще запомни себе си за вас."
„Запомнете себе си... Това звучи добре. Благодаря за урока.“
GO TO FULL VERSION