1 Attachment(s)
How to get certain bits from a value?
How do I get certain bits from a larger value? I am being passed an unsigned long as a function parameter and I need to get bits 0-15 and 16-23 out of it. How do I do this? (I know I have to use binary operators and shifts but I forgot how to do this exactly.) Thanks. :)
(Might want to see the attached drawing to get what I mean.)
Re: How to get certain bits from a value?
To filter out given bits in a value you typically use the AND operator (&). So, if you need the 2. and 3. bit (counting from 0 to n / right to left / least to most significant), you first determine the value of bit 2 and 3:
Code:
2^2 + 2^3 = 4 + 8 = 12
The answer is 12, now take your number and AND it with 12:
Code:
unsigned int value = 9; // 0. and 3. bit is set
unsigned int mask = 12; // value of 2. and 3. bit
unsigned int result = value & mask; // this should reult in 8 (ie. the 3. bit was set)
If you need the 16 least significant bits from a quad, you simply AND it with the sum of the 16 least significant bits:
Code:
unsigned int value = ...;
unsgiend int result = value & 0xffff; // 0xffff is the sum of the 16 LSBs
Or to get the value of bits 16..23:
Code:
unsigned int value = ...;
unsgiend int result = value & 0x00ff0000; // 0x00ff0000 is the sum of bits 16..23
In the latter example you may want to shift the result so that is fits into a byte. To do that you shift the result 16 positions to the right:
Code:
unsigned int value = ...;
unsgiend char result = (value & 0x00ff0000) >> 16;
- petter
Re: How to get certain bits from a value?
Re: How to get certain bits from a value?
or do it the easy way.
Code:
union Packet
{
unsigned long Value;
struct
{
unsigned long T: 1;
unsigned long P: 1;
unsigned long A: 1;
unsigned long Reserved: 4;
unsigned long E: 1;
unsigned long ScanCode: 8;
unsigned long RepeatCount: 16;
};
};
Code:
Packet x;
x.Value = 0xFFFFFFFF;
x.P = 0;
x.Reserved = 0x0C;
//etc.
Re: How to get certain bits from a value?
Hmm. I never knew about that technique. Thanks to you too! :)
Re: How to get certain bits from a value?
no problem i hope u undestand my example because idint explain alot of it
Re: How to get certain bits from a value?
Is this union/bitfields stuff guarated to work?
Re: How to get certain bits from a value?
Quote:
Originally Posted by Hobson
Is this union/bitfields stuff guarated to work?
Well, this is C, not C++ stuff. It works, but you gotta find out about the order of high/low bits - this may vary, depending on the compiler. You could do that with bytes, words, lwords; here you have to watch out for the order the bytes appear.
IE,
Code:
struct {
char x1:3;
char x2:5;
char x2:8;
}
is different from
Code:
struct {
int x1:3;
int x2:5;
int x3:8;
}
Re: How to get certain bits from a value?
Quote:
Originally Posted by Hobson
Is this union/bitfields stuff guarated to work?
No, not at all.
For example, I'm pretty sure Mitsukai's example won't work on most x86-32 compilers.
It's highly non-portable, because of bit order, bit fields storage size, and other bit field issues. It also introduces value representation issues, with problems of padding bits of unsigned long and bit order of the value representation of unsigned long.
Moreover, there might be aliasing issues (though, it's not very probable).
Re: How to get certain bits from a value?
its most likely this struct does not contain padding bits. since it only has one variable and it is an aggregate.
and what do you mean with bit order?
im pretty sure this works 99%
Re: How to get certain bits from a value?
Mitsukai
Therefore it is not guaranteed to work.
Re: How to get certain bits from a value?
it does not state that its not portable.
Quote:
You cannot portably specify more bits than are used to represent type int.
and we do not :)
Re: How to get certain bits from a value?
Quote:
Originally Posted by Mitsukai
it does not state that its not portable.
A bitfield on its own is indeed portable.
But a union of a bitfield and an integer is not portable, because the internal layout of the bitfield can change from compiler to compiler.
Re: How to get certain bits from a value?
ah ok, now that makes more sense.
maybe we could use memcpy on the aggregate instead?
Code:
struct Packet
{
unsigned long T: 1;
unsigned long P: 1;
unsigned long A: 1;
unsigned long Reserved: 4;
unsigned long E: 1;
unsigned long ScanCode: 8;
unsigned long RepeatCount: 16;
};
unsigned long slut = 0x0F0F0F0F
int main(void)
{
Packet x;
::memcpy(&x, &slut, sizeof(slut));
}
Re: How to get certain bits from a value?
You cannot know for certain where each field will end up inside the integer. T could be the most significant bit or the least significant bit, so could P or A.
So you cannot use a bitfield to get specific bits (eg. the least significant bit) from an integer.
:)