код C ++ для проверки, содержит ли целое число заданный шестнадцатеричный шаблон - PullRequest
0 голосов
/ 03 января 2012

У меня есть некоторые целые числа (64-разрядные), которые я хочу проверить, содержат некоторые шестнадцатеричные шаблоны.

Например, допустим, что целое число равно 0x00000B21, и я хочу проверить, содержит ли оно шаблон шестнадцатеричный 0x00000A20. Если я сделаю обычный (Num1 & Num2) == Num2, он проверит, содержит ли Num1 шаблон бинарный Num2. (В приведенном мной примере это вернет true, даже если шестнадцатеричные числа не совпадают.)

Какой хороший способ проверки шестнадцатеричных шаблонов?

Ответы [ 6 ]

9 голосов
/ 03 января 2012

Вы бы сделали (0x00000B21 & 0x00000FFF) == 0x00000A20.

Обычно, когда вы вычисляете маску, для каждого nybble ставьте F, если вы заинтересованы в значении, и 0, если вы не заинтересованы.

2 голосов
/ 03 января 2012

Простой способ сделать то, что вы хотите, и избежать проблемы, о которой вы говорите, это просто замаскировать шестнадцатеричные цифры, которые вам не нужны (размер вашего шаблона), а затем сравнить это с вашим шаблоном. , то есть:

#include <iostream>

int main(void)
{
   unsigned num1 = 0x00000B21;
   unsigned num2 = 0xABC0A20;
   unsigned pattern = 0xA20;

   std::cout << ((num1 & 0xFFF) == pattern) << std::endl;
   std::cout << ((num2 & 0xFFF) == pattern) << std::endl;

   return 0;
}

Выход:

0
1

Это будет также работать, когда вы хотите, чтобы в шаблон было включено 0.

2 голосов
/ 03 января 2012

Кажется, что может быть более элегантный способ, но это, безусловно, сработает:

(Num1 & Mask(Num2)) == Num2

, где мы определили Маску как:

uint64 Mask(uint64 x) {
  return 
    ((x & 0xF0000000) ? 0xF0000000 : 0) |
    ((x & 0x0F000000) ? 0x0F000000 : 0) |
    ((x & 0x00F00000) ? 0x00F00000 : 0) |
    ((x & 0x000F0000) ? 0x000F0000 : 0) |
    ((x & 0x0000F000) ? 0x0000F000 : 0) |
    ((x & 0x00000F00) ? 0x00000F00 : 0) |
    ((x & 0x000000F0) ? 0x000000F0 : 0) |
    ((x & 0x0000000F) ? 0x0000000F : 0);
}
1 голос
/ 03 января 2012

Сначала вы должны вычислить «маску», например,

unsigned long long mask = 0;
while (mask < num2) mask = (mask << 4) | 0x0F;
if ( (num1 & mask) == num2 ) ...

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

Обратите внимание, что эта проверка будет о поиске, если шестнадцатеричные цифры num2 равны в конце из num1. Это не то же самое, что ((num1 & num2) == num2) в двоичном формате.

0 голосов
/ 03 января 2012
long number = ...;
long pattern = ...;
for(int i = 0; i < 64; i++)
{
    if( ( (number >> i) & pattern) == pattern)
    {
        // true
        break;
    }
}
// false

Это должно работать.Извините, если это не совсем типичный (или компилируемый) код C ++.Я в основном пишу на Java.Во всяком случае, это все понятно.

0 голосов
/ 03 января 2012

Я бы использовал побитовую маску (Num1 & Num2) == Num2. Я думаю, что это предпочтительный способ сделать это. Вычислительно быстро и легко читается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...