我想提取十进制数字的位。
例如,7是二进制0111,我想得到0 1 1 1存储在bool中的所有位。我怎么能这样做?
好的,循环不是一个好选择,我可以为此做点什么吗?
答案 0 :(得分:137)
如果你想要n的第k位,那么
(n & ( 1 << k )) >> k
这里我们创建一个蒙版,将蒙版应用于n,然后右移蒙版值以获得我们想要的位。我们可以更全面地写出来:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
您可以阅读有关位屏蔽here的更多信息。
这是一个程序:
#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");
}
答案 1 :(得分:66)
根据要求,我决定将我对食指答案的评论延伸到一个完整的答案。虽然他的答案是正确的,但它是不必要的复杂。此外,所有当前答案都使用带符号的int
来表示值。这很危险,因为负值的右移是实现定义的(即不可移植),左移可能导致未定义的行为(见this question)。
通过将所需位右移到最低有效位,可以使用1
进行屏蔽。无需为每个位计算新的掩码值。
(n >> k) & 1
作为一个完整的程序,计算(并随后打印)单个位值的数组:
#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);
}
假设您想要计算所有位,而不是特定的位,可以将循环更改为
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
这会修改input
,从而允许使用恒定宽度的单比特移位,这在某些架构上可能更有效。
答案 2 :(得分:3)
这是一种方法 - 还有很多其他方法:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
答案 3 :(得分:2)
这是一种非常简单的方法;
int main()
{
int s=7,l=1;
vector <bool> v;
v.clear();
while (l <= 4)
{
v.push_back(s%2);
s /= 2;
l++;
}
for (l=(v.size()-1); l >= 0; l--)
{
cout<<v[l]<<" ";
}
return 0;
}
答案 4 :(得分:1)
如果您不想要任何循环,则必须将其写出来:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num = 7;
#if 0
bool arr[4] = { (num&1) ?true: false, (num&2) ?true: false, (num&4) ?true: false, (num&8) ?true: false };
#else
#define BTB(v,i) ((v) & (1u << (i))) ? true : false
bool arr[4] = { BTB(num,0), BTB(num,1), BTB(num,2), BTB(num,3)};
#undef BTB
#endif
printf("%d %d %d %d\n", arr[3], arr[2], arr[1], arr[0]);
return 0;
}
如此处所示,这也适用于初始化程序。
答案 5 :(得分:1)
@prateek感谢您的帮助。我重写了带有注释的函数,以便在程序中使用。增加8可获得更多位(整数最多可增加32位)。
std::vector <bool> bits_from_int (int integer) // discern which bits of PLC codes are true
{
std::vector <bool> bool_bits;
// continously divide the integer by 2, if there is no remainder, the bit is 1, else it's 0
for (int i = 0; i < 8; i++)
{
bool_bits.push_back (integer%2); // remainder of dividing by 2
integer /= 2; // integer equals itself divided by 2
}
return bool_bits;
}
答案 6 :(得分:0)
#include <stdio.h>
int main(void)
{
int number = 7; /* signed */
int vbool[8 * sizeof(int)];
int i;
for (i = 0; i < 8 * sizeof(int); i++)
{
vbool[i] = number<<i < 0;
printf("%d", vbool[i]);
}
return 0;
}