我正在尝试自己学习C.我遇到了这个练习,我正在学习理解它。我已经阅读了有关屏蔽位的内容,为了得到最后四位,我们应该做val& 0xF。我已经阅读了这篇文章What is Bit Masking?。我需要解释的部分是为什么可能的值是0x7,0xB,0xD,0xE,0xF。我正在研究答案,我已阅读各种文章。如果有人愿意向我解释这部分我会很感激。
答案 0 :(得分:3)
因为这些都是可能的数字,后四位中至少有三位。如果你记下从0到15的每个二进制数,你会看到它们至少有三个最后四位设置:
可以这样想:从0到6的每个二进制数最多设置2位:
因此,它们都不符合规则。从7到15,我们有:
从这些中,只有7,11,13,14和15设置了最后四位中的三个。
这种方法易于实现:
int chk_last_bits2(unsigned x) {
return ((x & 0x7) == 0x7) ||
((x & 0xB) == 0xB) ||
((x & 0xD) == 0xD) ||
((x & 0xE) == 0xE) ||
((x & 0xF) == 0xF);
}
请注意,我们必须为每种情况明确测试相等性。例如,x & 0xB
将为每个设置了1011
位的数字返回非零值。这不是我们想要的,我们希望所有这些都可以开启,可以用相等的方式进行测试。
另一种可能的解决方案是:
int chk_last_bits(unsigned x) {
int i, j;
for (i = 1, j = 0; i < 32; i <<= 1)
if (i & x)
j++;
return j >= 3;
}
因为你正在学习C,所以我会留下这个来试图理解。
答案 1 :(得分:1)
屏蔽意味着过滤比特并保留其中一些感兴趣的部分,正如您将理解的那样。
假设您有一个变量something
和一个mask
,两者都是unsigned
值:something & mask
将返回一个位为0
的值,其中掩码为0
,以及掩码为something
的{{1}}中的值。这是和掩码。
要理解为什么使用这些特定值,您必须回想一下按位操作(1
,&
...)在C中的工作方式。当您编写|
时,则使用指定的逻辑运算符有序地组合两个变量的相应位。例如,如果a & b
为a
且10001010
为b
,则00000011
为a & b
(有序,00000010
)。
如果您了解这一点,那么您可以了解这些面具将选择的内容。考虑他们的二进制表示:
1 and 0, 0 and 0, 0 and 0, 0 and 0, 1 and 0, 0 and 0, 1 and 1, 0 and 1
这是用于和屏蔽,用于提取值(请参阅您链接的答案)。 xor 和或屏蔽功能类似,只需回忆逻辑功能的行为。
答案 2 :(得分:0)
#include <stdio.h>
int main()
{
/*
32 Bit binary: 00000000000000001100101011111110
Decimal: 51966
*/
int val = 0xCAFE;
/*
Note:
First it does loop, after that it shifts the bits of `i`,
so `i` is 1 at the beginning.
When shifting operator appears always think of bits.
Step 1
Decimal: i = 1
32 Bit binary: 00000000000000000000000000000001
Step 2
Decimal: 1 << 1 = 2
32 Bit binary: 00000000000000000000000000000010
Step 3
Decimal: 2 << 1 = 4
32 Bit binary: 00000000000000000000000000000100
... and so on ... 1, 2, 4, 8, 16, 32, stop.
This indicates 2^n.
----------------------------------------------------------------
Inside the for loop we run the AND operator to find out
which bits are `on` and which are `off`.
AND only works if both are true.
Step 1:
Last bit
00000000000000000000000000000001
AND 00000000000000001100101011111110
---------------------------------
00000000000000000000000000000000
Decimal: 1
Second last bit
Step 2:
00000000000000000000000000000010
AND 00000000000000001100101011111110
---------------------------------
00000000000000000000000000000010
Decimal: 2
... and so on ...
As we can see we gradually check for last 4 bits until
we reach the 4th loop 2^4 = 32 and the loop stops.
*/
int i;
for (i = 1; i < 32; i = i << 1) {
/*
You can simply add a counter over here
and return the value at the end.
*/
printf("%d\n", i & val);
}
}