掩码和提取C中的位

时间:2014-10-14 10:54:30

标签: c mask bitwise-operators bit-shift bitwise-and

我一直在看关于面具的帖子,但仍然无法理解如何从C中的数字中提取某些位。

假如我们有一个int number 0001 1010 0100 1011,那么它的十六进制表示是x1a4b对吗?如果我想知道第5到第7个数字,在这种情况下是101,我应该使用int mask= 0x0000 1110 0000 0000, int extract = mask&number吗?

另外,我如何检查它是101?我想==在这里工作了......非常感谢!

7 个答案:

答案 0 :(得分:4)

假设gcc扩展名0b定义二进制文字:

int number = 0b0001101001001011; /* 0x1a4b */
int mask =   0b0000111000000000; /* 0x0e00 */
/* &'ed:     0b0000101000000000;    0x0a00 */
int extract = mask & number;     /* 0x0a00 */

if (extract == 0b0000101000000000)
/* or if 0b is not available:
if (extract == 0x0a00 ) */
{
  /* success */
}
else
{
  /* failure */
}

答案 1 :(得分:3)

通过设置除了你想要的那个位之外的所有位来完成屏蔽。所以假设你有一个8位变量,你想要检查第5位是否是1.让我们说你的变量是00101100。为了屏蔽所有其他位,我们使用&amp ;;将除了第5位之外的所有位设置为0。操作者:

00101100 & 00010000

现在这样做除了第5个之外的每个位,右边字节的位都是0,所以&的结果是操作将为0.但是,对于第5位,右位的值为1,因此结果将是左侧字节的第5位的值 - 在这种情况下为0:

现在要检查此值,您必须将其与某些内容进行比较。为此,只需将结果与右侧的字节进行比较:

result = (00101100 & 00010000) == 00000000

为了概括这一点,你可以通过左移00000001从左手字节中检索任何位,直到得到你想要的位。以下功能实现了这一目标:

int getBit(char byte, int bitNum)
{
    return (byte & (0x1 << (bitNum - 1)))
}

这适用于任何大小的变种,无论是8,16,32或64(或其他任何事情)。

答案 2 :(得分:1)

您需要屏蔽转变。移动您要比较的值,或者您要比较的值。通过改变你所比较的价值,我发现更容易思考。因此,如果您尝试提取第5到第7位(从左侧),您将向右 9个位置(16-7)移位,以便第7位数字现在最右边,然后应用0x7(二进制为111)作为掩码,仅获取最右边的三个二进制数字

int i = 0x1A4B;
if (((i >> 9) & 0x07) == 0x05) { // 0x05 = 101 in binary
    //do what you need to
}

答案 3 :(得分:1)

首先,二进制数字(通常)从右侧(第10位和第12位)计算,或者您说第5位和第7位最高位数

int mask =  0x0E00;  // 0000 1110 0000 0000;
int extract = mask & number;

结果:

extract = 0000 1010 0000 0000

你可以做到

if (extract == 0x0A00 /*0000 1010 0000 0000*/){}

进行测试,或者:

if (( extract >> 9 ) == 0x05){}

if中的两个语句将与您的样本号一起返回true。

通常使用面具,您会发现自己正在测试一个数字。您可以使用这样的函数来测试它:

bool digit_value( unsigned int number, unsigned int digit)
{
    return (1 << digit) & number;
}

int main()
{
    unsigned int number = 0x1A4B;
    int should_be_three = 0;
    should_be_three +=  digit_value(number, 10);
    should_be_three += !digit_value(number, 11);
    should_be_three +=  digit_value(number, 12);
    printf("%s", (should_be_three == 3?"it worked":"it didn't work"));
    return 0;
}

答案 4 :(得分:0)

我应该使用int mask = 0x0000 1110 0000 0000,int extract = mask&amp; number? - 是的,你可以这样做。

另外,如何检查是否为101? 当然你可以检查一下 - 0000 1010 0000 0000,这是1280 in int。

extract == 1280

答案 5 :(得分:0)

逐个检查位可能更简单,而不是一次检查。 首先,为感兴趣的位创建掩码:

int fifthBitMask = 1 << 4;
int fifthBitResult = number & fifthBitMask;

int seventhBitMask = 1 << 6;
int seventhBitResult = number & seventhBitMask;

现在,您可以将结果与掩码的零OR进行比较。 可以省略与零比较,因此您可以使用简单的if:

if (fifthBitResult && seventhBitResult)
{
    //your code here
}

此外,您可以与面具进行比较。在操作&amp;之后,结果将仅设置在掩码中设置的位。 所以,它可能是这样的:     if(fifthBitResult == fifthBitMask&amp;&amp; seventhBitResult == seventhBitMask)     {         //你的代码在这里     }

因此,如果操作结果等于掩码,则可以通过一个操作执行此操作:

int mask = 0x5 << 4; // 0x5 is hex representation of 101b
int result = number & mask;
if (result == mask)
{
    // your code here
}

答案 6 :(得分:0)

首先,您对位7-6-5的计算是 incorrct 。你说它是101但它是010(对于x1a43) 其次,要获取这些位(由这些位表示的值),您应该&0xE0

int my_bits_from_5to7 = number & 0xE0;