在 C 中屏蔽和提取位

sti*_*ons 5 c mask bit-shift bitwise-operators bitwise-and

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

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

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

Pan*_*nda 6

屏蔽是通过将所有位设置为 0 来完成的。假设您有一个 8 位变量,并且您想检查第 5 位是否为 1。假设您的变量为00101100。为了屏蔽所有其他位,我们使用 & 运算符将除第 5 位以外的所有位设置为 0:

00101100 & 00010000
Run Code Online (Sandbox Code Playgroud)

现在它所做的是对于除第 5 位以外的每一位,右边字节的位将为 0,因此 & 操作的结果将为 0。然而,对于第 5 位,右边位的值是a 1,因此结果将是从左字节起第 5 位的任何值 - 在这种情况下为 0:

现在要检查这个值,你必须将它与某些东西进行比较。为此,只需将结果与右侧的字节进行比较:

result = (00101100 & 00010000) == 00000000
Run Code Online (Sandbox Code Playgroud)

概括地说,您可以通过左移 00000001 直到获得您想要的位来从左侧字节中检索任何位。以下函数实现了这一点:

int getBit(char byte, int bitNum)
{
    return (byte & (0x1 << (bitNum - 1)))
}
Run Code Online (Sandbox Code Playgroud)

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


alk*_*alk 5

假设 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 */
}
Run Code Online (Sandbox Code Playgroud)