-
Bit processing in C
I am attempting to check the values of the various bits in an 8-bit field and struggle as I might, success seems to elude me. Please help.
I need to check each bit for the following values:
bit 7 - x'80'
bit 6 - x'40'
bit 5 - x'20'
bit 4 - x'10'
bit 3 - x'08'
bit 2 - x'04'
bit 1 - x'02'
bit 0 - x'01'
:) Many thanks !
-
Normally you use a bit mask (set known bits on or off) and then use the & operator
Code:
int is_set(unsigned char test_value)
{
unsigned char bit=1;
int result= bit & test_value;
return result;
}
This tests to see if bit zero - the low order bit is set. It returns 1 if the bit is set, 0 if clear.
you can use << n (the shift left operator) to move the "position" of the set bit n places over.
-
how abt something like
Code:
bool is_bit_set(unsigned char byte,unsigned char check_bit)
{
if(check_bit>7 || (byte & (1<<check_bit)) ==0)
return false;
return true;
}
so you pass it the byte and the bit position to check from 0 to 7.. it returns true/false based on if the bit is set/not set
edit: and before anyone points out the above code assumes the machine is little endian..
-
>and before anyone points out the above code assumes the machine is little endian..
Urm.. no it doesn't. There's no endianism going on here at all.
-
ok lets assume the machine is big-endian
Code:
byte to check :- 00000010
mask 1(big endian) :- 10000000
now i want to check if the 1st bit is set which in the above case is yes
1U << 1 :- 00000000
now 00000010
& 00000000
-----------------------
00000000
and the result is 0 which is the bit is not set... but the bit is actually set...
Now I am confused.. may be I am wrong can some one clarify...
-
Endianness is related to storage, not to a value. A value, say 123, does not change due to endianness; the underlying storage may be different.
(And your representation of mask 1 is backwards.)
-
Code:
(1<<check_bit) ==0
needs to be changed to
(1U<<check_bit) ==0
as from the other thread i learnt that signed integer breaks when bitshifiting from one endian to the other...
-
Endianism relates to the way bytes are ordered in memory, not the bits per se.
For instance say I have this value
0x12345678 this is a 32 bit value, say an int.
because machines are typically byte addressed, it could be stored like this
Code:
address value
0 0x12
1 0x34
2 0x56
3 0x78
This is big endian.
or stored like this
Code:
address value
0 0x78
1 0x56
2 0x34
3 0x12
this is little endian.
In your example, since there is only one byte, there is no issue with endianism.
As a rule, you don't need to worry about endianism if you solely use the normal bit masking/shifting idiom for accessing bits, or just use (solely) bit fields. If you mix them then you can get into trouble.
Also, if you start splitting an int into bytes to access the component bits, then you need to be careful.
-
Code:
unsigned char i = 3;
if(i & 1) { /* will be true */
printf("\nBit 1 is set");
}
The i & 1 operation is doing something like this in computer memory:
Code:
i = 00000011; /* binary */
if(
00000011
& 00000001
= 00000001
true) {
}
I hope this helps. :)
dwk