У меня есть параметр int с возможными значениями 1,2,4,8,16,32,64.
int
Мне нужно знать битовое смещение текущего значения, т. Е. Для каждого возвращаемого значения 1, 2, 3, 4, 5 или 6 соответственно.
Какой самый простой способ добиться этого?
У вас есть несколько ответов здесь: 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, справочная таблица может быть самой простой и быстрой
Вот версия, которая делает максимум пять итераций для 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; }
Все, что вам нужно сделать, это циклически менять и сдвигать каждый раз. Но есть более быстрый способ использования переключателя. перечисляя оба для вас.
//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; }