Programming in C

(Barry) #1

294 Chapter 12 Operations on Bits


or you can set the typefield to the value n, where nis between 0 and 255 ,by the
statement
packed_data |= n << 18;
To ensure that nis between 0 and 255 ,you can AND it with 0xff before it is shifted.
Of course, the preceding statements only work if you know that the typefield is
zero; otherwise, you must zero it first by ANDing it with a value (frequently called a
mask) that consists of 0 s in the eight bit locations of the typefield and 1 s everywhere
else:
packed_data &= 0xfc03ffff;
To save yourself the bother of having to explicitly calculate the preceding mask, and also
to make the operation independent of the size of an integer, you could instead use the
following statement to set the typefield to zero:
packed_data &= ~(0xff << 18);
Combining the statements described previously, you can set the typefield of
packed_datato the value contained in the eight low-order bits of n,irrespective of any
value previously stored in this field, with the following statement:
packed_data = (packed_data & ~(0xff << 18)) | ((n & 0xff) << 18);
In the preceding code, some of the parentheses are superfluous but were added to aid
readability.
You can see how complex the preceding expression is for accomplishing the relatively
simple task of setting the bits in the typefield to a specified value. Extracting a value
from one of these fields is not as bad:The field can be shifted into the low-order bits of
the word and then ANDed with a mask of the appropriate bit length. So, to extract the
typefield of packed_dataand assign it to n, the statement
n = (packed_data >> 18) & 0xff;
does the trick.
The C language does provide a more convenient way of dealing with bit fields.This
method uses a special syntax in the structure definition that allows you to define a field
of bits and assign a name to that field.Whenever the term “bit fields” is applied to C, it is
this approach that is referenced.
To define the bit field assignments previously mentioned, you can define a structure
called packed_struct,for example, as follows:
struct packed_struct
{
unsigned int :3;
unsigned int f1:1;
unsigned int f2:1;
unsigned int f3:1;
unsigned int type:8;
unsigned int index:18;
};
Free download pdf