Получить битовое смещение в C ++ - PullRequest
1 голос
/ 04 января 2012

У меня есть параметр int с возможными значениями 1,2,4,8,16,32,64.

Мне нужно знать битовое смещение текущего значения, т. Е. Для каждого возвращаемого значения 1, 2, 3, 4, 5 или 6 соответственно.

Какой самый простой способ добиться этого?

Ответы [ 3 ]

4 голосов
/ 04 января 2012

У вас есть несколько ответов здесь: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious самое простое, если у вас есть входное значение без знака int v:

unsigned int r = 0; // r will be lg(v)

while (v >>= 1) // unroll for more speed...
{
  r++;
}

но это изменит v в процессе.

edit: в вашем случае, если вы на 100% уверены, что ваш ввод и int и степень 2, справочная таблица может быть самой простой и быстрой

1 голос
/ 04 января 2012

Вот версия, которая делает максимум пять итераций для 32-битного значения, в отличие от ответа лезбулона, который имеет наихудший случай 32 итераций. Адаптация к 64-битным значениям увеличивает число итераций в этой версии до шести, а в худшем - до 64.

int get_pos (unsigned v)
{
  int s=16,p=0,m=0xffff;

  while (s)
  {
    if (v>>s) p += s;
    v = (v | (v >> s)) & m;
    s >>= 1;
    m >>= s;
  }

  return p;
}
0 голосов
/ 04 января 2012

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

//more code but awesomely fast
int getBitOffset1(int d) {
  switch(d) {
    case 1: return 1;
    case 2: return 2;
    case 4: return 3;
    case 8: return 4;
    case 16: return 5;
    case 32: return 6;
    /* keep adding case upto sizeof int*8 */
  }
}

//less code, the loop goes 64 times max
int getBitOffset2(int d) {
  int seed=0x01;
  int retval=0;
  do{
    if(seed<<retval == d) {
      break;
    }
    retval++;
  }while(retval<=sizeof(int)*8);
  return retval+1;
}

int main() {
    printf("%d\n", getBitOffset2(32));
    printf("%d\n", getBitOffset2(1));
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...