In
Embedded systems C programming, bit-fields offer great benefits in
terms of optimization and flexibility for programmers. However if not
used with care it can produce adverse results. In this post, let us
look into signed
qualifiers
affecting output of the bit-field structure. Please note code
snippets provided here is tested with GCC compiler [ gcc version
4.7.3 ] running under Linux environment.
Let
us consider a simple small 'C' code snippet (as shown in the Fig 1
below), with a structure named bit_field,
namely
having three integer fields hours,
mins
and secs
having bit size of 5,6 and 6 respectively.
Fig
1: Definition of the bit-field structure.
Now
let us declare a variable alarm
of struct
time_t
and
set values as 22, 12 and 20 respectively.
Fig 2: Value assignment for structure members
When
we print these values using (simple printf statement) what could be
the output? At first sight most of us will envision answers will be
22, 12 and 20 for
hours,
mins
and secs
field.
Whereas when we actually compile and run the value would be different
-10, 12 and 20 (as mentioned in Fig 3 below). Now what’s wrong with
this? Isn’t it obvious to print an integer value?
Fig
3: Actual output
What
and where did we go wrong? Let us give some work to our grey matter!
- We all know that default signed qualifier for the “int” is “signed int”
- In our case, we reserved '5' bits for storing the hours field assuming we are using 24 hrs format. So, among '5' bits '1' bit is used for storing the sign of the number, which means only 4 bits are now available for storing actual value. In this 4 bits we can store the numbers ranging from -16 to +15 according to the formula (-2^k) to (+2^(k-1)) including “0”, where 'k' indicating number of bits.
- We will see how 22 is stored in binary form in this '5' bits through pictorial representation, shown in Fig 4
b4
|
b3
|
b2
|
b1
|
b0
|
1
|
0
|
1
|
1
|
0
|
Fig
4: Pictorial representation of binary value of 24 in '5' bits
- From the above table, it is very clear that sign bit (b4) is SET which indicates the value is negative. So, when printed using the printf statement we will get -10 (Decimal value of 10110) because of which we are getting unexpected output.
Now
that we understand the problem, how do we fix it? It is very simple
just qualify “int” to “unsigned int” just before the hours
in the bit-field structure as shown below Fig 5 with corrected output
in Fig 6.
Fig
5: “int” qualified to “unsigned int“
Fig
6: Correct output after correct usage of datatype
Bit wise operators
definitely provide advantages, which need to be used ‘bit’
carefully. In Embedded programming environment they might lead to
major issues in case of not handling it properly.
No comments:
Post a Comment