First of all, I want to know if this is possible: let's say I have an unsigned long which contains some abritrary unsigned shorts, which may or may not be in the number. For example:
unsigned short int id1 = 3456,
id2 = 30998;
unsigned long long bitfld = id1|id2;
Can the other 2 fields be assumed as 0? And is OR the right operation for this? After that let's say I pass bitfld as an argument:
void dostuff (unsigned long long bf)
{
//pseudo code
if( the first field exists in bf)
get first field;
if( the second field exists in bf)
get second field;
//etc...
}
I think I have to poll out the first 16 bits of the bitfield and check those, then recursively poll them, verif开发者_开发知识库y them and store them if they are greater than 0. But I'm not sure how to do this, bit shifting only shifts left or right, thus, it only divides or multiplies right?
sorry for the bump. Thanks all for your answers, but I ended up using a simpler and more efficient method, an internal structure. You see, I could have done this easily with a string, but my purpose was transparency to the user of the code, easy to program so to say. I created an internal structure to hold my values and then a public method to create and return such structure, so it is easy to use and faster to parse (though it has the overhead of allocating in the stack a (albeit small) structure, which the bit field solution hasn't, but alas).
So thank you all for your answers.
short int
is 2 bytes long, but long long
is 8 bytes, so you have some kind of length mismatch;
You may have meant this:
unsigned long long bitfld = id1|(id2<<16);
you can check is there is a field occupied by AND
ing it like:
void dostuff (unsigned long long bf)
{
//pseudo code
if(bf & 0xFFFF)
return bf & 0xFFFF;
if(bf & 0xFF00)
return (bf & 0xFFFF0000) >> 32;
//etc...
}
The bitwise OR operation is not what you want. The operation will merge existing bits with the new bits. You want an operation that replaces bits.
So first, you will need to clear out the bits using AND and NOT:
unsigned short int id1 = 3456,
id2 = 30998;
unsigned long long bitfld;
unsigned short int all_ones = ~0;
const unsigned int id2_position = 1;
const unsigned int bits_to_shift_left = id2_position * sizeof(unsigned short) * CHAR_BIT;
unsigned long long mask = ~(all_ones << bits_to_shift_left);
bitfld = bitfld & mask; // Erase all bits in id2 position
bitfld = bitfld | (id2 << bits_to_shift_left); // Put value into second position.
Unless lack of memory space is an issue, this kind of bit packing is not worth the development effort, validation time and extra execution time. Place the values into a "packed" buffer of unsigned char, then use the buffer with I/O.
You probably should review the bitshift operators and how they work. If you simply do:
id1 | id2
, you basically mashed all the bits together. You would not be able to extract these values individually later. What you wanted to do is something like id1 | (id2 << 16)
as pointed out by the user alemjerus.
Another way of accomplishing the same goal without bitshitting is to use a union:
struct s_btfld {
unsigned short int f1;
unsigned short int f2;
unsigned short int f3;
unsigned short int f4;
};
union u_btfld {
struct s_btfld fields;
unsigned long long value;
};
Now you can do:
unsigned short int id1 = 3456, id2 = 30998;
union u_btfld bitfld;
bitfld.fields.f1 = id1;
bitfld.fields.f2 = id2;
dostuff(bitfld.value);
And in dostuff, you can easily retrieve the fields by:
void dostuff(unsigned long long bf) {
union u_btfld a;
a.value = bf;
printf("id1 = %d\n", a.fields.f1);
printf("id2 = %d\n", a.fields.f2);
}
Assuming unsigned short is 2 bytes and an unsigned long is 4 bytes.
unsigned short id1 = 0x0d80; //3456 decimal
unsigned short id2 = 0x7916; //30998 decimal
unsigned long bitfld = ((id2<<16)|id1) //id2<<16 = 0x79160000, so bitfld = 0x79160d80
if ((bitfld & id1) == id1) {
//id1 is in lower 2 bytes of bitfld
}
if ((bitfld>>16) &id2) == id2) { //bitfld>>16 = 0x00007916
//id2 is in upper 2 bytes of bitfld
}
Does this help? When dealing with bits it's easier to visually see what is happening if you work with hex values.
精彩评论