Здравствуйте!
Дано: Двухбайтовая битовая маска.
Задача: сравнить биты данной маски (к примеру, 13-ый и 14-ый).
Решение:
unsigned short bitMask = 0x6000; // (0110 0000 0000 0000)
int bitFlag = 3; // (0000 0000 0000 0000 0000 0000 0000 0011) in 32-bit arch
// todo
if ( (bitMask&(bitFlag<<13))>>13 == bitFlag )
{
// bits are proprietary
}
На мой взгляд, конструкция корявая (сдвинули, сложили, опять сдвинули, потом сравнили результат с эталонным). Тем более в большом проекте такая конструкция будет вводить в ступор программистов.
Возможно, существуют более изящные приемы работы с битовыми массивами?
Спасибо.
Алексей
>[оверквотинг удален]
> {
> // bits are proprietary
> }
>
два бита удобно сравнивать xor-ом - он дает нуль, если биты одинаковые
то есть у тебя условие будет типа( (1<<pos1) & bitmask) ^ ( (1 <<pos2) & bitmask )
Курсовая, зачёт?
if ((bitMask >> 13) & bitFlag ) // так вполне хватает---
Ща найду полезную сцылку...
> Ща найду полезную сцылку...
> Курсовая, зачёт?
>
> if ((bitMask >> 13) & bitFlag ) // так вполне хватает
>Кстати, пофеншую - с маской сравнивают, а не двигают её!
if ((bitFlag << 13) & bitMask) // так феншуйнее.
Собственно, последний вариант и использую в "курсовой". А статья действительно хорошая. Спасибо.
Только немного так:
unsigned mask; // input bitmask
unsigned flag; // given checked mask
unsigned bits;
if (mask^(flag<<bits))
{
// all flag's bits are equal to mask
}
> Только немного так:
> if (mask^(flag<<bits))
> {
> // all flag's bits are equal to mask
> }
>(mask ^(flag << bits)) == FALSE,
XOR даёт 1 (TRUE) если биты разные!!!
И ваще, вот эти 4 таблицы надо наизусть знать, иначе препод расстреляет.
AND OR XOR NOT
0 & 0 = 0 0 | 0 = 0 0 ^ 0 = 0 ~0 = 1
0 & 1 = 0 0 | 1 = 1 0 ^ 1 = 1 ~1 = 0
1 & 0 = 0 1 | 0 = 1 1 ^ 0 = 1
1 & 1 = 1 1 | 1 = 1 1 ^ 1 = 0
Полностью с Вами согласен, и дело даже не в преподавателях - за этот проект мне платят деньги (на работе), но я только еще учусь. XOR в данном случае даст true , если все проверяемые биты совпали и false - если хоть один бит не совпал, что отвечает Вашему замечанию. Однако в моем коде проверяется условие на true - видимо в теле условия мне необходимо выполнить действия, соответствующие несовпадению по маске - я просто неправильно описал алгоритьм в примере.
> видимо в теле условия мне необходимо выполнить действия, соответствующие несовпадению по маскеНе совпадут с маской ВСЕ, кроме маски :)
Каюсь
>> Курсовая, зачёт?
>>
>> if ((bitMask >> 13) & bitFlag ) // так вполне хватает
>>
> Кстати, пофеншую - с маской сравнивают, а не двигают её!
>
> if ((bitFlag << 13) & bitMask) // так феншуйнее.
>херовый у вас фэншуй.
по-хорошему, на рантайме ничего никуда сдвигать вообще не надо,
а надо иметь уже сдвинутое значение и с ним уже делать and/xor/whatever
Дано: двухбайтовая битовая маска (набор из 16 битов)
Задача: проверить на соответствие 13-ый и 14-ый бит (считывается из конфига в виде, допустим, тоже двухбайтового числа, принимаемого значения 0, 1, 2 и 3).
Ваши предложения?
> Дано: двухбайтовая битовая маска (набор из 16 битов)
> Задача: проверить на соответствие 13-ый и 14-ый бит (считывается из конфига в
> виде, допустим, тоже двухбайтового числа, принимаемого значения 0, 1, 2 и
> 3).
> Ваши предложения?((mask XOR value) AND 0xFFFF) = 0 - совпало
0xFFFF заменяется на маску сравниваемых битов (в поставленной задаче - биты 13-14). что проще?
делаем XOR, потом отсекаем ненужные биты в результате.
> ((mask XOR value) AND 0xFFFF) = 0 - совпалоSHL/SHR работают быстрее XOR
>> ((mask XOR value) AND 0xFFFF) = 0 - совпало
> SHL/SHR работают быстрее XORКто бы спорил. Просто дал альтернативный псевдокод.
Так, что если смотреть сколько машинных тактов, занимает выполнение конкретной команды, то Вы правы на все 100%. Если быть чуть ближе к реальности, то мой вариант тоже вполне жизнеспособен.
PS
к тому же если внимательно вчитаться в начальный вопрос, на который я и отвечал:
"
Здравствуйте!
Дано: Двухбайтовая битовая маска.
Задача: сравнить биты данной маски (к примеру, 13-ый и 14-ый).
Решение:
"то там нигде не сказано, что в маске не будет "паразитных" битов с неизвестным значением. требуется только сравнить 13-14 бит полученной маски (читай - случайное значение) с данными. простой сдвиг в этом случае, как с "точной" маской не прокатит.
Фактически, вопрос поставлен так, что маска является по сути абсолютно неизвестными входными данными, которые требуется сравнить с другими.
> Фактически, вопрос поставлен так, что ...Фактически, вопрос был: как упростить (A & ( B << C )) >> C == D ) :)
>> Фактически, вопрос поставлен так, что ...
> Фактически, вопрос был: как упростить (A & ( B << C ))
> >> C == D ) :)+1000
чувствую себя идиотом.
> PS
> к тому же если внимательно вчитаться в начальный вопрос, на который я
> и отвечал:
> "
> Здравствуйте!
> Дано: Двухбайтовая битовая маска.
> Задача: сравнить биты данной маски (к примеру, 13-ый и 14-ый).
> Решение:вообще вопрос можно было понять как "одинаковы ли значения 13 и 14 бита в маске"
> с неизвестным значением. требуется только сравнить 13-14 бит полученной маски (читай
> - случайное значение) с данными.правильная постановка вопроса, имхо - "установлены ли в данной маске одновременно биты 13 и 14"
если позиции 13 и 14 жестко заданы и не меняются на рантайме - тогда вообще никаких сдвигов не надо
#define LOVELY_BIT_MASK ((1<<13) | (1<<14))if ( (our_mask & LOVELY_BITMASK) == LOVELY_BITMASK) - вполне покатит
если маска однобитная - то и сравнивать не надо
>[оверквотинг удален]
>> с неизвестным значением. требуется только сравнить 13-14 бит полученной маски (читай
>> - случайное значение) с данными.
> правильная постановка вопроса, имхо - "установлены ли в данной маске
> одновременно биты 13 и 14"
> если позиции 13 и 14 жестко заданы и не
> меняются на рантайме - тогда вообще никаких сдвигов не надо
> #define LOVELY_BIT_MASK ((1<<13) | (1<<14))
> if ( (our_mask & LOVELY_BITMASK) == LOVELY_BITMASK) -
> вполне покатит
> если маска однобитная - то и сравнивать не надо
#define LOVELY_BITMASK ((1<<13) | (1<<14))const int our_mask = 0b0011000000000000;
const int bitFlag = 0b0011;inline int love(void) {
return ( (our_mask & LOVELY_BITMASK) == LOVELY_BITMASK);
}inline int shr_and(void) {
return ( (our_mask >> 13 ) & bitFlag);
}# gcc -O0 test.c
# objdump -d test.o
0000000000000000 <love>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # a <love+0xa>
a: 25 00 60 00 00 and $0x6000,%eax
f: 3d 00 60 00 00 cmp $0x6000,%eax
14: 0f 94 c0 sete %al
17: 0f b6 c0 movzbl %al,%eax
1a: 5d pop %rbp
1b: c3 retq000000000000001c <shr_and>:
1c: 55 push %rbp
1d: 48 89 e5 mov %rsp,%rbp
20: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 26 <shr_and+0xa>
26: 89 c2 mov %eax,%edx
28: c1 fa 0d sar $0xd,%edx
2b: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 31 <shr_and+0x15>
31: 21 d0 and %edx,%eax
33: 5d pop %rbp
34: c3 retq# gcc -Ofast test.c
# objdump -d test.o
0000000000000000 <love>:
0: 31 c0 xor %eax,%eax
2: c3 retq
3: 66 66 66 66 2e 0f 1f data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
a: 84 00 00 00 00 000000000000000010 <shr_and>:
10: b8 01 00 00 00 mov $0x1,%eax
15: c3 retq
>
> inline int shr_and(void) {
> return ( (our_mask >>
> 13 ) & bitFlag);
> }
>так не прокатит, хотя идея ясна. надо так видимо (в терминах автора):
((bitMask >> 12 ) == bitFlag);
> #define LOVELY_BIT_MASK ((1<<13) | (1<<14))
> if ( (our_mask & LOVELY_BITMASK) == LOVELY_BITMASK) -" == LOVELY_BITMASK " - лишнее.
>> #define LOVELY_BIT_MASK ((1<<13) | (1<<14))
>> if ( (our_mask & LOVELY_BITMASK) == LOVELY_BITMASK) -
> " == LOVELY_BITMASK " - лишнее.неа . если 2 бита надо - не лишнее
иначе может сработать по одному биту
>> PS
>> к тому же если внимательно вчитаться в начальный вопрос, на который я
>> и отвечал:
>> "
>> Здравствуйте!
>> Дано: Двухбайтовая битовая маска.
>> Задача: сравнить биты данной маски (к примеру, 13-ый и 14-ый).
>> Решение:
> вообще вопрос можно было понять как "одинаковы ли значения 13
> и 14 бита в маске"тогда скорее уж как (если смотреть код автора) установлены ли биты маски (bitMask) 13 и 14 в заданное значение (bitFlag).
ИМХО не знаю кто там такой умный - препод или студент, что путает определение данных, масок и флагов.
>[оверквотинг удален]
>> с неизвестным значением. требуется только сравнить 13-14 бит полученной маски (читай
>> - случайное значение) с данными.
> правильная постановка вопроса, имхо - "установлены ли в данной маске
> одновременно биты 13 и 14"
> если позиции 13 и 14 жестко заданы и не
> меняются на рантайме - тогда вообще никаких сдвигов не надо
> #define LOVELY_BIT_MASK ((1<<13) | (1<<14))
> if ( (our_mask & LOVELY_BITMASK) == LOVELY_BITMASK) -
> вполне покатит
> если маска однобитная - то и сравнивать не надо
> херовый у вас фэншуй.
> а надо иметь уже сдвинутое значениеА кто это значение должен "уже сдвинуть"? Само? :)
>> херовый у вас фэншуй.
>> а надо иметь уже сдвинутое значение
> А кто это значение должен "уже сдвинуть"? Само? :)компилятор. дефайны. сюрприз ?
хотя для динамически вычисляемых масок не катит, конечно же..