【发布时间】:2016-01-05 10:54:50
【问题描述】:
我正在尝试遍历 unsigned char 的位,但我不确定从哪里开始,最终,我将对位执行其他按位操作,例如 ~ 和 xor..等。
【问题讨论】:
-
您是否考虑一次对所有这些进行操作?
标签: c bit-manipulation bit
我正在尝试遍历 unsigned char 的位,但我不确定从哪里开始,最终,我将对位执行其他按位操作,例如 ~ 和 xor..等。
【问题讨论】:
标签: c bit-manipulation bit
循环位可以通过多种方式完成:
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
}
}
【讨论】:
bits 为 0 时停止。
此函数将允许您遍历一个单词中的所有设置位:
inline size_t next_bit(uint64_t bf, size_t bit) {
return ctz(bf & ~((1UL << bit) -1));
}
ctz 函数计算应由编译器作为内置函数提供的尾随零的数量。对于 gcc 和 llvm,您可以使用以下内容(请注意,对于 x86 上的 0,ctz 未定义,因此需要修复):
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.
该函数通过清除ith 位之前的所有位并计算尾随零的数量来工作,这将为您提供ith 位之后的下一个设置位。清除这些位的方法是首先将一个位移到ith 位置,减去一个将所有位设置为低于ith 位的位。然后我们可以NOT 掩码来获取i 之后的所有位,以便AND 操作将删除i 之后的所有位。 ctz 完成剩下的工作。
对于 unsigned char 来说,这有点(双关语)矫枉过正,但我无法抗拒。老实说,对于 8 位字,您最好使用其他答案中建议的简单 while 循环。
【讨论】:
嗯,从最低位到最高位,你可以这样循环:
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 位进行操作(并在用完时停止而不是完成所有八个循环)等。需要更多上下文来解决特定问题问题而不是一般的循环。 Many specific problems are most efficiently solved with clever bit twiddling hacks.
【讨论】:
#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;
}
【讨论】:
此方法允许将数组的索引与枚举器中的值进行映射,而不管元素的顺序或数组中存储了多少元素:
typedef NS_OPTIONS(uint8_t, CaptureDeviceConfigurationControlPropertyBit) {
CaptureDeviceConfigurationControlPropertyBitTorchLevel = 1<< 0,
CaptureDeviceConfigurationControlPropertyBitLensPosition = 1<< 1,
CaptureDeviceConfigurationControlPropertyBitExposureDuration = 1<< 2,
CaptureDeviceConfigurationControlPropertyBitISO = 1<< 3,
CaptureDeviceConfigurationControlPropertyBitZoomFactor = 1<< 4,
};
typedef CaptureDeviceConfigurationControlPropertyBit CaptureDeviceConfigurationControlPropertyBitMask;
CaptureDeviceConfigurationControlPropertyBitMask mask = (CaptureDeviceConfigurationControlPropertyBitTorchLevel |
CaptureDeviceConfigurationControlPropertyBitLensPosition|
CaptureDeviceConfigurationControlPropertyBitExposureDuration|
CaptureDeviceConfigurationControlPropertyBitISO|
CaptureDeviceConfigurationControlPropertyBitZoomFactor);
do{
printf("mask\t==\t%d\n", (CaptureDeviceConfigurationControlPropertyBitMask)mask);
} while((mask ^= mask & (0- mask)) != 0.0);
【讨论】:
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 全天候在线为您服务。