Нахождение битовых позиций в 32-битном целом без знака - PullRequest
8 голосов
/ 29 июня 2010

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

У меня есть 32-битное целое число без знака (давайте использовать значение: 28)

Согласно некоторой документации, которую я перехожу, значение целого числа содержит флаги, определяющие различные вещи.

Позиции битов внутри флага нумеруются от 1 (младший порядок) до32 (высокий порядок).Все неопределенные биты флага зарезервированы и должны быть установлены в 0.

У меня есть таблица, которая показывает значения флагов со значением для чисел 1-10.

Я надеюсь, чтокто-то может попытаться объяснить мне, что все это означает, и как найти значения «флага» из числа, такого как 28, на основе позиции бита.

Спасибо

Ответы [ 7 ]

11 голосов
/ 29 июня 2010

28 преобразуется в 11100 в двоичном виде.Это означает, что биты 1 и 2 не установлены, а биты 3, 4 и 5 установлены.

Несколько моментов: во-первых, любой, кто действительно привык к C, обычно начинает нумерацию с 0, а не с 1. Во-вторых,Вы можете проверить отдельные флаги с помощью побитового оператора и оператора (&), например:

#define flag1 1    //  1 = 00 0001
#define flag2 2    //  2 = 00 0010
#define flag3 4    //  4 = 00 0100
#define flag4 8    //  8 = 00 1000
#define flag5 16   // 16 = 01 0000
#define flag6 32   // 32 = 10 0000

if (myvalue & flag1)
    // flag1 was set

if (myvalue & flag4)
    // flag4 was set

и так далее.Вы также можете проверить, какие биты установлены в цикле:

#include <stdio.h>

int main() { 
    int myvalue = 28;
    int i, iter;

    for (i=1, iter=1; i<256; i<<=1, iter++)
        if (myvalue & i)
            printf("Flag: %d set\n", iter);
    return 0;
}

должно вывести:

Flag: 3 set
Flag: 4 set
Flag: 5 set
9 голосов
/ 15 октября 2011

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

Предположим, что битовое поле находится в (переменном скалярного целого) переменного поля.

while (field){
  temp = field & -field;  //extract least significant bit on a 2s complement machine
  field ^= temp;  // toggle the bit off
  //now you could have a switch statement or bunch of conditionals to test temp
  //or get the index of the bit and index into a jump table, etc.
}

Работает довольно хорошо, когда битовое поле не ограничено размером одного типа данных, но может иметь произвольный размер. В этом случае вы можете извлекать 32 (или любой другой размер вашего регистра) биты за раз, проверять его на 0 и затем переходить к следующему слову.

3 голосов
/ 29 июня 2010

Чтобы получить int со значением 0 или 1, представляющим только n -й бит из этого целого числа, используйте:

int bitN = (value >> n) & 1;

Но обычно это не то, что вы хотитеделать.Более распространенная идиома:

int bitN = value & (1 << n);

В этом случае bitN будет 0, если бит n не установлен, и ненулевым в случае, если nбит установлен.(В частности, это будет любое значение, полученное только с установленным n -ым битом.)

0 голосов
/ 10 февраля 2016
// You can check the bit set positions of 32 bit integer.
// That's why the check is added "i != 0 && i <= val" to iterate till 
// the end bit position.
    void find_bit_pos(unsigned int val) {
            unsigned int i;
            int bit_pos;
            printf("%u::\n", val);
            for(i = 1, bit_pos = 1; i != 0 && i <= val; i <<= 1, bit_pos++) { 
                    if(val & i)
                            printf("set bit pos: %d\n", bit_pos);
            }
    }
0 голосов
/ 30 мая 2015

Небольшое изменение ответа @ invaliddata-

unsigned int tmp_bitmap = x;        
while (tmp_bitmap > 0) {
    int next_psn = __builtin_ffs(tmp_bitmap) - 1;
    tmp_bitmap &= (tmp_bitmap-1);
    printf("Flag: %d set\n", next_psn);
}
0 голосов
/ 02 августа 2014

Используйте функцию журнала с основанием 2. В python это будет выглядеть так:

import math 

position = math.log(value, 2)

Если позиция не является целым числом, то более 1 бита было установлено в 1.

0 голосов
/ 29 июня 2010

Предполагается, что flags не подписано ...

int flag_num = 1;
while (flags != 0)
{
    if ((flags&1) != 0)
    {
        printf("Flag %d set\n", flags);
    }
    flags >>= 1;
    flag_num += 1;
}

Если flags подписано, вы должны заменить

flags >>= 1;

с

flags = (flags >> 1) & 0x7fffffff;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...