Що означає "(int) значення & 0x1, (int) значення & 0x2, (int) значення & 0x4, (int) значення & 0x8"? "


11

код

"Значення" коливається від 0 до 15 (можливі його значення). Коли будуть виконані ці 4 "якщо" умови? Якщо моє (int) значення = 2, це означає 0010?

            if  ((int)value & 0x1) 
            {
                //statement here
            }
            if  ((int)value & 0x2) 
            {
                //statement here
            }
            if  ((int)value & 0x4) 
            {
                //statement here
            }
            if  ((int)value & 0x8) 
            {
                //statement here
            }

3
Це бітові маски, які перевіряють окремі біти value(читайте if(value & 0x4)як "Чи є третій біт valueнабору (= ​​1)). Оскільки у вас, здавалося б, є проблеми з розумінням коду, я припускаю, що він не ваш. Це (і те, що ви не запитуєте для огляду) робить це питання не по темі для CR.SE .
Nobody

Для кращого розуміння, аналогічний код, який був перенесений на C #, буде використовувати Enum.HasFlagметод для тестування на біти. Див: Enum.HasFlag .
rwong

Відповіді:


12

Кожне число може бути виражене, як value = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ...кожен b є або 0або 1(це біти подання). Це бінарне подання.

Двійковий AND ( &) сприймає кожну з цих bпар, які виконують І на них. Це має такі результати:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

Використовуючи потужності 2 (які мають лише один біт), ми можемо виділити і протестувати окремі біти:

  • value & 1вірно, коли valueнепарно {1, 3, 5, 7, 9, 11, 13, 15}.

  • value & 2вірно, коли value/2непарно {2, 3, 6, 7, 10, 11, 14, 15}.

  • value & 4вірно, коли value/4непарно {4, 5, 6, 7, 12, 13, 14, 15}.

  • value & 8вірно, коли value/8непарно {8, 9, 10, 11, 12, 13, 14, 15}.

Префекс 0x для чисел означає, що його слід інтерпретувати як шістнадцяткове число . Це трохи зайве, коли ви піднімаєтеся лише до 0x8, але повідомляєте, що його, мабуть, використовують як біт-маску.


1
Формулювання може припустити, що його можна поширити на всі числа, що не відповідає дійсності: 8/6непарне, а 8&6помилкове.
Sjoerd

@Sjoerd, тому я сказав "сили 2"
храповик виродка

5

Ці if-заяви перевіряють, чи встановлено певний біт value.

Наприклад, у шістнадцятковому значенні 0x4є 3-й біт від правого набору 1та до всіх інших бітів 0. Якщо ви використовуєте двійковий і оператор ( &) з двома операторами, в результаті буде встановлено всі біти, за 0винятком тих бітів, які в обох оперантів є 1.

Тому , коли ви робите розрахунок value & 0x4, ви або отримати двійковий 00000000або двійковий 00000100, в залежності від того , чи немає 3 - й біт valueє 1або 0. Перший оцінює до false, а другий до true, тому блок if виконується лише для значень, де встановлений 3-й біт.


1

Тут слід зазначити дві цікаві речі.

По-перше, це загальна модель для перевірки кожного 4 біта низького порядку інтегрального значення. Умова if виконується, якщо встановлено відповідний біт. Для значення 2 бітовий малюнок дійсно є 0010.

Інше цікавіше запитання - чому саме (int)акторський склад ? Окрім поганого стилю використання C-casts у C ++, жодних цілих чи знакових значень цей склад не потребує. Буль не має сенсу, подвійний / float буде перетворений на ціле тимчасове, і було б незвично використовувати буквальні значення для тестування enum. Це може мати сенс указівника, але це було б дуже спеціалізованим використанням. Висновок: акторський склад не має сенсу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.