如果最后四位(LSB)中至少有三位开启,则int val=0xCAFE测试

如果最后四位(LSB)中至少有三位开启,则int val=0xCAFE测试,c,bit-manipulation,mask,C,Bit Manipulation,Mask,我正在努力自学C语言。我偶然发现了这个练习,我正在学习理解它。我读过关于掩蔽位的内容,为了得到最后四位,我们应该使用val&0xF。我也读过这篇文章。我需要解释的部分是为什么可能的值是0x7,0xB,0xD,0xE,0xF。我正在研究答案,我读过很多文章。如果有人愿意向我解释这一部分,我将不胜感激。掩蔽意味着过滤位并只保留其中一些位,正如您所理解的那样,这些位是感兴趣的 假设您有一个变量something和一个mask,两者都是无符号的值:something&mask将返回一个位为0的值,其中m

我正在努力自学C语言。我偶然发现了这个练习,我正在学习理解它。我读过关于掩蔽位的内容,为了得到最后四位,我们应该使用val&0xF。我也读过这篇文章。我需要解释的部分是为什么可能的值是0x7,0xB,0xD,0xE,0xF。我正在研究答案,我读过很多文章。如果有人愿意向我解释这一部分,我将不胜感激。

掩蔽意味着过滤位并只保留其中一些位,正如您所理解的那样,这些位是感兴趣的

假设您有一个变量
something
和一个
mask
,两者都是
无符号的
值:
something&mask
将返回一个位为
0
的值,其中mask为
0
,以及它们在
something
中的值,其中mask为
1
。这是你的头像和面具

为了理解为什么要使用这些特定值,您必须回忆一下按位操作(
&
|
…)在C中是如何工作的。当您编写
a&b
时,两个变量的对应位将使用指定的逻辑运算符有序组合。例如,如果
a
10001010
b
00000011
,那么
a&b
00000010
(依次为
1和0、0和0、0和0、0和0、1和0、0和0、1和1

如果您理解了这一点,那么您就可以理解这些遮罩将选择什么。考虑它们的二进制表示:


这是用于和屏蔽的,用于提取值(请参阅链接的答案)。xor和or掩蔽的工作原理类似,只要回想一下逻辑函数的行为就可以了。

掩蔽意味着过滤位并只保留其中一些位,正如您所理解的那样,这些位是感兴趣的

假设您有一个变量
something
和一个
mask
,两者都是
无符号的
值:
something&mask
将返回一个位为
0
的值,其中mask为
0
,以及它们在
something
中的值,其中mask为
1
。这是你的头像和面具

为了理解为什么要使用这些特定值,您必须回忆一下按位操作(
&
|
…)在C中是如何工作的。当您编写
a&b
时,两个变量的对应位将使用指定的逻辑运算符有序组合。例如,如果
a
10001010
b
00000011
,那么
a&b
00000010
(依次为
1和0、0和0、0和0、0和0、1和0、0和0、1和1

如果您理解了这一点,那么您就可以理解这些遮罩将选择什么。考虑它们的二进制表示:


这是用于和屏蔽的,用于提取值(请参阅链接的答案)。异或和或屏蔽的工作原理类似,只要回忆一下逻辑函数的行为就可以了。

因为这些都是可能的数字,最后四位中至少有三位是开着的。如果您记下0到15之间的每个二进制数,您将看到这些二进制数至少设置了最后四位中的三位:

  • 0111(0x7)
  • 1011(0xB)
  • 1101(0xD)
  • 1110(0xE)
  • 1111(0xF)
可以这样想:从0到6的每个二进制数最多设置2位:

  • 0(0)
  • 1(1)
  • 第10(2)条
  • 11(3)
  • 100(4)
  • 101(5)
  • 110(6)
因此,所有这些都不符合规则。从7日到15日,我们有:

  • 111(7)
  • 1000(8)
  • 1001(9)
  • 1010(10)
  • 1011(11)
  • 1100(12)
  • 1101(13)
  • 1110(14)
  • 1111(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;
}
int-chk\u最后一位(无符号x){
int i,j;

对于(i=1,j=0;i<32;i,因为这些都是可能的数字,最后四位中至少有三位打开。如果你记下0到15之间的每个二进制数,你会发现这些数字至少设置了最后四位中的三位:

  • 0111(0x7)
  • 1011(0xB)
  • 1101(0xD)
  • 1110(0xE)
  • 1111(0xF)
可以这样想:从0到6的每个二进制数最多设置2位:

  • 0(0)
  • 1(1)
  • 第10(2)条
  • 11(3)
  • 100(4)
  • 101(5)
  • 110(6)
因此,没有一个符合规则。从7到15,我们有:

  • 111(7)
  • 1000(8)
  • 1001(9)
  • 1010(10)
  • 1011(11)
  • 1100(12)
  • 1101(13)
  • 1110(14)
  • 1111(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;
}
int-chk\u最后一位(无符号x){
int i,j;
对于(i=1,j=0;i<32;i
#包括
int main()
{
/*
32位二进制文件:0000000000000000 11001010111110
十进制:51966
*/
int val=0xCAFE;
/*
注:
首先它循环,然后它移动