5

我一直在看有关掩码的帖子,但仍然不知道如何从 C 中的数字中提取某些位。

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

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

4

7 回答 7

6

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

00101100 & 00010000

现在,除了第 5 位之外的每一位,右侧字节的位将为 0,因此 & 运算的结果将为 0。但是,对于第 5 位,右侧的值是a 1,因此结果将是从左字节开始的第 5 位的值 - 在本例中为 0:

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

result = (00101100 & 00010000) == 00000000

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

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

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

于 2014-10-14T11:09:10.123 回答
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 */
}
于 2014-10-14T11:25:07.493 回答
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
}
于 2014-10-14T11:06:20.730 回答
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;
}
于 2014-10-14T11:12:49.773 回答
0

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

另外,我怎样才能检查它是否是101?当然你可以检查这个 - 0000 1010 0000 0000这是1280int.

extract== 1280
于 2014-10-14T11:05:43.403 回答
0

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

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

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

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

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

此外,您可以与口罩进行比较。在操作 & 之后,结果中将只设置掩码中设置的位。所以,它可能是这样的: if (fifthBitResult == FifthBitMask && SevenBitResult == SevenBitMask) { // 你的代码在这里 }

因此,如果运算结果等于掩码,您可以通过一个操作来做到这一点:

int mask = 0x5 << 4; // 0x5 is hex representation of 101b
int result = number & mask;
if (result == mask)
{
    // your code here
}
于 2014-10-14T11:09:54.933 回答
0

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

int my_bits_from_5to7 = number & 0xE0;

于 2014-10-14T11:11:34.183 回答