按位操作和掩码:返回掩码中设置的原始变量的位值



这是我第一次在这里想知道以前没有人问过同样的问题,因此我不得不自己问一下:)

有一个设备(不会深入讨论,因为它现在无关紧要),我正在使用我有两个输入,每个输入的长度为16位。第一个输入包含后面需要的值,第二个输入包含"位置"。从这里我们要找到第一个输入的值。我来举个例子:

编辑:澄清:掩码可以是16位长度和8位设置的任何东西。不只是有最低的两口(1),只是简单地说明这个场景。

input:  0101 1011 0000 0111
mask:   0011 0011 0011 0011
output: 0001 0011 0000 0011

当mask设置为1时,机器需要返回输入的值,无论它是1还是0,都无关紧要。设备使用该值,而不考虑后面的值。

我可以找到解决方案,这与简单的&,如上所述,但它不是足够的因为我的硬件有其局限性,有资源可以得救。如示例所示,掩码可能只包含最大8位设置,因为电路板上的一些东西是互斥的,我想并且可以使我的输出长度仅为8位:

output: xx01 xx11 xx00 xx11
saved to a variable as: 0111 0011

…我只是还不知道该怎么做。

那么我应该如何进行,我应该建立一个数组,在那里我保存掩码的设置位的位置,然后检查输入的值,或者有一个更有效的方法来做到这一点。关于扫描值等并不重要,因为我可以处理它,目前我们可以将输入和掩码视为任何16位长整数。在这段简短的代码中,我使用了与前面的二进制示例相同的模拟十进制值。

#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t input=23303;   //1st input, gives the 1s and 0s to be extracted
uint16_t mask=13107;    //2nd input, defines the locations of needed 1s and 0s
uint8_t fi;             //Filtered inputs=input after masking, this one to be returned
/*something needs to be done here*/
return fi;              //With these inputs, this should be 115
return 0;
}

掩码可以是任何16位长度和8位设置. ...

遍历input & mask的结果,并在每次迭代中检查掩码位是否设置。如果设置,则在8位结果中设置相应位

你可以这样做:

#include <stdio.h>
#include <inttypes.h>
int main (void) {
uint16_t input = 23303;
uint16_t mask = 13107;
uint8_t fi = 0;
uint16_t res = input & mask;

for (unsigned int x = 0, c = 0; res; res >>= 1, ++x) {
if ((mask >> x) & 0x1) {
if (res & 0x1) {
fi |= 0x1 << c;
} 
c++;
}
}
printf ("fi : %" PRIu8 "n", fi);
return 0;
}

输出:

% ./a.out
fi : 115

16位长度和8位设置的其他掩码值尝试上述解决方案。

最简单的方法:

#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t input=23303;   //1st input, gives the 1s and 0s to be extracted
uint16_t mask=13107;    //2nd input, defines the locations of needed 1s and 0s
uint8_t fi;             //Filtered inputs=input after masking, this one to be returned

/*something needs to be done here*/
uint16_t temp = input & mask;
uint8_t np0, np1, np2, np3;
np0 = temp &0x03;
np1 = (temp >> 4) & 0x03;
np2 = (temp >> 8) & 0x03;
np3 = (temp >> 12) & 0x03;

fi = np0 | (np1 << 2) | (np2 << 4) | (np3 << 6);
return fi;              //With these inputs, this should be 115
return 0;
}

有点复杂,但可能更快:# include & lt; stdio.h># include & lt; stdint.h>

int main()
{
uint16_t input=23303;   //1st input, gives the 1s and 0s to be extracted
uint16_t mask=13107;    //2nd input, defines the locations of needed 1s and 0s
uint8_t fi;             //Filtered inputs=input after masking, this one to be returned

/*something needs to be done here*/

fi = (temp &0x03) | ((temp >> 2) & 0x0C) | ((temp >> 4) & 0x30) | ((temp >> 6) & 0xC0);
return fi;              //With these inputs, this should be 115
return 0;
}