Reputation: 113
I'm trying to loop through the bits of an unsigned char, but I'm not sure where to start, eventually, I'll perform other bitwise operating on the bits, such as ~ and xor..etc.
Upvotes: 5
Views: 17599
Reputation: 1525
This method allows maps the indicies of an array with values in an enumerator, regardless of the order of elements or how many elements are stored in the array:
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);
Upvotes: 0
Reputation: 2180
#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;
}
Upvotes: 0
Reputation: 2957
This function will allow you to iterate through all set bits in a word:
inline size_t next_bit(uint64_t bf, size_t bit) {
return ctz(bf & ~((1UL << bit) -1));
}
The ctz
function counts the number of trailing zeroes which should be provided by your compiler as a built-in function. For gcc and llvm, you can use the following (note that ctz
is undefined for 0
on x86 hence the fixup):
inline size_t ctz(uint64_t x) { return x ? __builtin_ctzll(x) : 64; }
Here's an example of how to use it in a for-loop:
for (size_t i = next_bit(bf, 0); i < 64; i = next_bit(bf, i + 1))
// the i-th bit is set.
The function works by clearing away all the bits preceding the i
th bit and counting the number of trailing zeroes which will provide you with the next set bit after the i
th bit. Clearing the bits is accomplished by first shifting a bit into the i
th position, subtracting one which sets all the bits lower then the i
th bit. We can then NOT
the mask to get all the bits after i
so that an AND
op will remove all the bits after i
. ctz
does the rest.
It's a bit (pun intended) overkill for an unsigned char but I couldn't resist. Honestly, for 8-bit words, you're better off with a simple while loop as proposed in the other answers.
Upvotes: 2
Reputation: 33
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 (" ");
}
}
If you don't understand this code please comment, I'm 24x7 online for you.
Upvotes: -1
Reputation: 155438
Well, from lowest to highest bit, you can loop like so:
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
}
}
That's a really general use case though; typically, you want to parallelize your work (operate on a whole byte at a time), or only operate on the 1 bits (and stop when you run out instead of finishing all eight loops), etc. More context is needed to solve specific problems rather than general looping. Many specific problems are most efficiently solved with clever bit twiddling hacks.
Upvotes: 0
Reputation: 726639
Looping over bits can be done in several ways:
1
.Here is an example of the first approach:
unsigned int bits = ...;
while (bits) {
if (bits & 1) {
// Current bit is set to 1
} else {
// Current bit is set to 0
}
bits >>= 1;
}
If you want to continue working with bits after you reach zero, make a separate counter.
Here is an example of the second approach:
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
}
}
Upvotes: 12