Bad*_*adr 95 c bit-manipulation
我想提取十进制数的位.
例如,7是二进制0111,我想得到0 1 1 1存储在bool中的所有位.我怎么能这样做?
好的,循环不是一个好选择,我可以为此做点什么吗?
for*_*ger 144
如果你想要n的第k位,那么就做
(n & ( 1 << k )) >> k
Run Code Online (Sandbox Code Playgroud)
在这里,我们创建一个蒙版,将蒙版应用于n,然后右移蒙版值以获得我们想要的位.我们可以更全面地写出来:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
Run Code Online (Sandbox Code Playgroud)
您可以在此处阅读有关位屏蔽的更多信息.
这是一个程序:
#include <stdio.h>
#include <stdlib.h>
int *get_bits(int n, int bitswanted){
int *bits = malloc(sizeof(int) * bitswanted);
int k;
for(k=0; k<bitswanted; k++){
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
bits[k] = thebit;
}
return bits;
}
int main(){
int n=7;
int bitswanted = 5;
int *bits = get_bits(n, bitswanted);
printf("%d = ", n);
int i;
for(i=bitswanted-1; i>=0;i--){
printf("%d ", bits[i]);
}
printf("\n");
}
Run Code Online (Sandbox Code Playgroud)
Joe*_*Joe 72
根据要求,我决定将我对食指答案的评论延伸到一个完整的答案.虽然他的答案是正确的,但它是不必要的复杂.此外,所有当前答案都使用带符号的ints来表示值.这是危险的,因为负值的右移是实现定义的(即不可移植),左移可能导致不确定的行为(参见这个问题).
通过将所需位右移到最低有效位位置,可以完成屏蔽1.无需为每个位计算新的掩码值.
(n >> k) & 1
Run Code Online (Sandbox Code Playgroud)
作为一个完整的程序,计算(并随后打印)单个位值的数组:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
unsigned
input = 0b0111u,
n_bits = 4u,
*bits = (unsigned*)malloc(sizeof(unsigned) * n_bits),
bit = 0;
for(bit = 0; bit < n_bits; ++bit)
bits[bit] = (input >> bit) & 1;
for(bit = n_bits; bit--;)
printf("%u", bits[bit]);
printf("\n");
free(bits);
}
Run Code Online (Sandbox Code Playgroud)
假设您要在这种情况下计算所有位,而不是特定位,则可以进一步将循环更改为
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
Run Code Online (Sandbox Code Playgroud)
这input在适当的位置进行了修改,从而允许使用恒定宽度的单比特移位,这在某些架构上可能更有效.
这是一种方法 - 还有许多其他方法:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
Run Code Online (Sandbox Code Playgroud)
很难理解为什么不希望使用循环,但展开循环很容易:
bool b[4];
int v = 7; // number to dissect
b [0] = 0 != (v & (1 << 0));
b [1] = 0 != (v & (1 << 1));
b [2] = 0 != (v & (1 << 2));
b [3] = 0 != (v & (1 << 3));
Run Code Online (Sandbox Code Playgroud)
或者评估最后四个语句中的常量表达式:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
Run Code Online (Sandbox Code Playgroud)