以无符号32位整数查找位位置

时间:2010-06-29 16:51:21

标签: c bit-manipulation

我想我在谈到比特位置时可能已经在我的CS课上睡着了,所以我希望有人能伸出援助之手。

我有一个无符号的32位整数(让我们使用值:28)

根据我要查看的一些文档,整数的值包含指定各种内容的标志。

标志内的位位置从1(低位)到32(高位)编号。 所有未定义的标志位都是保留的,必须设置为0。

我有一个表格,显示标志的含义,数字1-10的含义。

我希望有人可以尝试向我解释这一切意味着什么,以及如何根据比特位置从数字28中找到“标志”值。

由于

7 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分:9)

不是循环遍历每一个位,而是只能循环遍历设置位,如果您希望稀疏地设置位,则可以更快:

假设位字段在(标量整数)变量字段中。

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进行测试,然后继续下一个单词。

答案 2 :(得分:3)

要获得int,其值01仅代表该整数的n位,请使用:

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

但这通常不是你想要做的。一个更常见的习语是:

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

在这种情况下,如果未设置bitN位,则0将为n,而在设置n位的情况下,n将为非零。 (具体来说,它只是{{1}}位设置的任何值。)

答案 3 :(得分:0)

假设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;

答案 4 :(得分:0)

使用带有基数2的日志功能。在python中,它看起来像:

import math 

position = math.log(value, 2)

如果position不是整数,则将1位以上设置为1.

答案 5 :(得分:0)

@ 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);
}

答案 6 :(得分:0)

// 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);
            }
    }