我试图循环遍历无符号字符的位,但我不知道从哪里开始,最终,我将对这些位执行其他按位操作,例如〜和xor..etc。
答案 0 :(得分:6)
循环比特可以通过多种方式完成:
1
生成的单位掩码来执行非破坏性循环。以下是第一种方法的示例:
unsigned int bits = ...;
while (bits) {
if (bits & 1) {
// Current bit is set to 1
} else {
// Current bit is set to 0
}
bits >>= 1;
}
如果要在达到零后继续使用位,请创建一个单独的计数器。
以下是第二种方法的示例:
unsigned int bits = ...;
for (int pos = 0 ; pos != 16 ; pos++) {
if (bits & (1 << pos)) {
// Current bit is set to 1
} else {
// Current bit is set to 0
}
}
答案 1 :(得分:2)
此函数允许您遍历单词中的所有设置位:
inline size_t next_bit(uint64_t bf, size_t bit) {
return ctz(bf & ~((1UL << bit) -1));
}
ctz
函数计算编译器应作为内置函数提供的尾随零的数量。对于gcc和llvm,您可以使用以下内容(请注意,x86上的ctz
未定义0
因此修复了):
inline size_t ctz(uint64_t x) { return x ? __builtin_ctzll(x) : 64; }
以下是如何在for循环中使用它的示例:
for (size_t i = next_bit(bf, 0); i < 64; i = next_bit(bf, i + 1))
// the i-th bit is set.
该功能通过清除i
位之前的所有位并计算尾随零的数量来工作,这将为您提供i
位之后的下一个设置位。通过首先将位移位到i
位置,减去将所有位设置为低于i
位的位来完成清除位。然后,我们可以NOT
掩码获取i
之后的所有位,以便AND
op将删除i
之后的所有位。剩下的就是ctz
。
对于一个未签名的字符有点过分(双关语),但我无法抗拒。老实说,对于8位字,你可以使用其他答案中提出的简单while循环来改善。
答案 2 :(得分:0)
好吧,从最低位到最高位,你可以这样循环:
unsigned char somebyte = ...;
for (int i = 0; i < 8; ++i, somebyte >>= 1) {
if (somebyte & 0x1) {
// Do stuff for 1 bit
} else {
// Do stuff for 0 bit
}
}
这是一个非常普遍的用例;通常,您希望并行化您的工作(一次操作一个整个字节),或者只对1位进行操作(当您用完而不是完成所有8个循环时停止)等等。需要更多上下文来解决具体问题。问题而不是一般循环。 Many specific problems are most efficiently solved with clever bit twiddling hacks.
答案 3 :(得分:0)
#define BIT(a,b) (a & (1<<b))
void printBits(unsigned char c){
int i;
char bits[9];
for( i=0;i<8;i++){
bits[i]=BIT(c,i)?'1':'0';
}
bits[8]=0;
char *fmt=isalpha(c)
?"'%c'\t= '%s'\n"
:" %d\t= '%s'\n";
printf(fmt,c,bits);
}
int main(){
printBits('A');
printBits('B');
printBits(1);
printBits(2);
printBits(3);
return 0;
}
答案 4 :(得分:-1)
Void PrintBits(unsigned int no)
{
Unsigned int mask = 0x8000;//=1000 0000 0000 0000 for 16 bit integers
For(I=0;I<16;I++){
If((i&mask)!=0)printf("1");
Else printf ("0");
Mask>>=1;
If(i%4==0)printf (" ");
}
}
如果您不理解此代码,请评论,我是24x7在线为您服务。