I have this function here to count 1 bits in a byte. However, when I try putting the char value of 200, it breaks. However, if I changed the char to unsigned char, it works. I am curious as to why.
int bit_counter (char b){
char count = 0;
while (b != 0){
if (b & 0x01){
count ;
}
b = b >> 1;
}
return count;
}
CodePudding user response:
This one is pretty tricky, and we have to look at the composition of a char.
First it works well, when you have 0 < b < 128 in your function.
What you use is a signed char. A signed char is composed of a sign bit and 7 bits of data. Meaning you can only have with 7 bits values from -128 to 127. char representation here.
When you assign b = 200 you have an overflow, meaning you go beyond 127 and it will take another value represented by 200. I assume the compiler takes the binary representation of 200 which is:
1100 1000 : The 1 in bold is the value of the sign bit (here indicating it is negative).
When you bit shift the content of b, you shift only the data bits. So the next iterations would look like:
1110 0100
1111 0010
1111 1001
...
1111 1111
Which corresponds to the value -1 (see two's complement. A zero representation for char is 0000 0000. So b will never be 0, and you are stuck in an infinite loop...
If you want to fix the issue you can use unsigned char (without the sign bit, replaced by data), or you could iterate over the size of the b type:
int bit_counter (char b){
char count = 0;
// sizeof(type) = byte size and -1 because there is the sign bit
for(int bitIndex = 0; bitIndex < (sizeof(char) * 8) - 1; bitIndex){
if (b & 0x01){
count ;
}
b = b >> 1;
}
return count;
}
CodePudding user response:
In the modern c better to go with standard library std::bitset. Like many people said in comments, you might have understood the disadvantage of using inbuilt types.
The std::bitset<N> has a function count which returns you the bits that are set to true (1).
Few examples
std::bitset<8> testBitSet { "11110000" }; //std::bitset<N> -- N (num of bits)
std::cout << testBitSet.count() << std::endl; //4
std::bitset<8> testBitSet2{ "11111111" };
std::cout << testBitSet2.count() << std::endl; //8
//The first 8 are considered
std::bitset<8> testBitSet4{ "00000011111111" }; //2
std::cout << testBitSet4.count() << std::endl;
//Construcing with a number
std::bitset<8> testBitSetWithNum(200);
std::cout << testBitSetWithNum.count() << std::endl; //3
std::cout << testBitSetWithNum << std::endl; //11001000
