简体   繁体   English

在无符号 32 位整数中查找位位置

[英]Finding Bit Positions in an unsigned 32-bit integer

I think I might have been asleep in my CS class when they talked about Bit Positions, so I am hoping someone can lend a hand.当他们谈论 Bit Positions 时,我想我可能在 CS 课上睡着了,所以我希望有人能伸出援手。

I have a unsigned 32-bit integer (Lets use the value: 28)我有一个无符号的 32 位整数(让我们使用值:28)

According to some documentation I am going over, the value of the integer contains flags specifying various things.根据我正在阅读的一些文档,整数的值包含指定各种事物的标志。

Bit positions within the flag are numbered from 1 (low-order) to 32 (high-order).标志内的位位置从 1(低位)到 32(高位)编号。 All undefined flag bits are reserved and must be set to 0.所有未定义的标志位都是保留的,必须设置为 0。

I have a Table that shows the meanings of the flags, with meaning for the numbers 1-10.我有一个表格,显示了标志的含义,其中数字 1-10 的含义。

I am hoping that someone can try and explain to me what this all means and how to find the "flag" value(s) from a number like, 28, based off of bit position.我希望有人可以尝试向我解释这一切意味着什么以及如何根据位位置从诸如 28 之类的数字中找到“标志”值。

Thanks谢谢

28 converts to 11100 in binary. 28以二进制形式转换为11100。 That means bits 1 and 2 are not set and bits 3, 4 and 5 are set. 这意味着未设置位1和2,并设置位3,4和5。

A few points: first, anybody who's really accustomed to C will usually start the numbering at 0, not 1. Second, you can test of individual flags with the bitwise and operator ( & ), as in: 几点:首先,任何真正习惯于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

and so on. 等等。 You can also check which bits are set in a loop: 您还可以检查循环中设置的位:

#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;
}

should print: 应该打印:

Flag: 3 set
Flag: 4 set
Flag: 5 set

Instead of looping through every single bit, you can instead loop through only the set bits, which can be faster if you expect bits to be sparsely set: 您可以改为仅循环设置位,而不是循环遍历每个位,如果您希望稀疏地设置位,则可以更快:

Assume the bit field is in (scalar integer) variable field. 假设位字段在(标量整数)变量字段中。

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.
}

Works pretty well when the bit field is not limited to the size of a single data type, but could be of some arbitrary size. 当位字段不限于单个数据类型的大小时,可以很好地工作,但可以是任意大小。 In that case, you can extract 32 (or whatever your register size is) bits at a time, test it against 0, and then move on to the next word. 在这种情况下,您可以一次提取32(或任何您的寄存器大小)位,对0进行测试,然后继续下一个字。

To get an int with the value 0 or 1 representing just the n th bit from that integer, use: 要获取值为01int ,表示该整数中的第n位,请使用:

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

But that's not usually what you want to do. 但这通常不是你想要做的。 A more common idiom is this: 一个更常见的习语是:

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

In this case bitN will be 0 if the n th bit is not set, and non-zero in the case that the n th bit is set. 在这种情况下bitN将是0 ,如果n个位未设置,并且所述的情况下的非零n个位被设置。 (Specifically, it'll be whatever value comes out with just the n th bit set.) (具体来说,它只是第n位设置的任何值。)

Use a log function, with base 2. In python, that would look like: 使用基数为2的日志函数。在python中,它看起来像:

import math 

position = math.log(value, 2)

If position is not an integer, then more than 1 bit was set to 1. 如果position不是整数,则将1位以上设置为1。

A slight variation of @invaliddata's answer- @ 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);
}

Assuming flags is unsigned... 假设flags是未签名的......

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

If flags is signed you should replace 如果签署了flags ,则应替换

flags >>= 1;

with

flags = (flags >> 1) & 0x7fffffff;
// 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);
            }
    }

Let's say that you have an array of integers, and you want to find all the positions (32-bit positions) where the bits are set collectively ie for a particular bit position how many set bits you will have in total by considering all the integers.假设您有一个整数数组,并且您想找到所有位被集体设置的位置(32 位位置),即对于特定位位置,通过考虑所有整数,您总共将拥有多少位设置位. In this case what you can do is that check for every Integer and mark its set bit position :在这种情况下,您可以做的是检查每个 Integer 并标记其设置位位置:

// let arr[n] is an array of integers of size n.
int fq[33] = {0} // frequency array that will contain frequency of set bits at a particular position as 1 based indexing.
for(int i=0; i<n; i++) {
   int x = arr[i];
   int pos = 1; // bit position
   for(int i=1; i<=pow(2,32); i= i<<1) {  // i is the bit mask for checking every position and will go till 2^32 because x is an integer.
      if(x & i) fq[pos]++;
      pos++;
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM