Checking if a bit is set in a byte
Just wondering if there is an easy way to check if a bit is set in a byte.
So, if I wanted to see it bit 5 was set for example?
Thanks in advance
bool IsBitSet( unsigned char byte, int index )
{
int mask = 1<<index;
return (byte & mask) != 0;
}
When you AND two values together, every bit that wasn't 1 in *both* values is set to zero. So if you want to check if a certain bit is set, you AND that one bit to a value, and then see if the result is 0 (the bit wasn't present), or if the result is the same what you AND'd.
if( (10110 & 10000) == 10000 )
if( (value & mask) == mask )
You can drop the " == mask " part because, in C++, non-zero integers automaticly convert to 'true':
if(value & mask) //If the result is 00000, then the statement evaluates to false, otherwise it evaluates to true.
Hodgeman's func does the same thing, but also uses an index to create the mask by shifting the value 00000001 over N places to become (for example) 00010000.
bool IsBitSet( unsigned char byte, int index ) { int mask = 1<<index; return (byte & index) != 0; }
I think you meant to use mask and not index in your return statement.
Here is the results I get with Clang 3.3 with -O3:
IsBitSet(unsigned char, int): # @IsBitSet(unsigned char, int)
btl %esi, %edi
setb %al
ret
is_bit_set(unsigned char, int): # @is_bit_set(unsigned char, int)
btl %esi, %edi
setb %al
ret
and with GCC 4.9 with -O3:
IsBitSet(unsigned char, int):
mov ecx, esi
mov eax, 1
movzx edi, dil
sal eax, cl
test eax, edi
setne al
ret
is_bit_set(unsigned char, int):
movzx eax, dil
mov ecx, esi
sar eax, cl
and eax, 1
ret
When you AND two values together, every bit that wasn't 1 in *both* values is set to zero. So if you want to check if a certain bit is set, you AND that one bit to a value, and then see if the result is 0 (the bit wasn't present), or if the result is the same what you AND'd.
if( (10110 & 10000) == 10000 )
if( (value & mask) == mask )
You can drop the " == mask " part because, in C++, non-zero integers automaticly convert to 'true':
if(value & mask) //If the result is 00000, then the statement evaluates to false, otherwise it evaluates to true.
Hodgeman's func does the same thing, but also uses an index to create the mask by shifting the value 00000001 over N places to become (for example) 00010000.
This actually seems to work very well. Easy to understand too
if( (10110 & 10000) == 10000 )
if( (value & mask) == mask )
I wonder, why do some people write "== mask" instead of "!= 0"? I suppose it doesn't matter much when the variable is "mask" and/or you use a function, but I've seen this pattern with huge blocks of hard-coded if checks with duplicated giant enum names everywhere.
if( (10110 & 10000) == 10000 )
if( (value & mask) == mask )
I wonder, why do some people write "== mask" instead of "!= 0"? I suppose it doesn't matter much when the variable is "mask" and/or you use a function, but I've seen this pattern with huge blocks of hard-coded if checks with duplicated giant enum names everywhere.
Consider what happens if mask contains more than one bit set. Comparing the AND-result against the mask checks if all bits are set, while comparing against 0 checks if any bit is set.
In that case it is not a matter of relative style or convention, but a matter of absolute correctness; one is correct and the other one is wrong.