Reputation: 8077
I'm reading some values from a single byte. I'm told in the user-manual that this one byte contains 3 different values. There's a table that looks like this:
I interpret that has meaning precision takes up 3 bits, scale takes up 2 and size takes up 3 for a total of 8 (1 byte).
What I'm not clear on is:
1 - Why is it labeled 7 through 0 instead of 0 through 7 (something to do with significance maybe?)
2 - How do I extract the individual values out of that one byte?
Upvotes: 16
Views: 21490
Reputation: 22979
You can do this via bitwise arithmetic:
uint precision = (thatByte & 0xe0) >> 5,
scale = (thatByte & 0x18) >> 3,
size = thatByte & 7;
Upvotes: 2
Reputation: 837926
1. Yes, the most significant bit is usually written first. The left-most bit is labeled 7 because when the byte is interpreted as an integer, that bit has value 27 (= 128) when it is set.
This is completely natural and is in fact is exactly the same as how you write decimal numbers (most significant digit first). For example, the number 356 is (3 x 102) + (5 x 101) + (6 x 100).
2. For completion, as mentioned in other answers you can extract the individual values using the bit shift and bitwise-and operators as follows:
int size = x & 7;
int scale = (x >> 3) & 3;
int precision = (x >> 5) & 7;
Important note: this assumes that the individual values are to be interpreted as positive integers. If the values could be negative then this won't work correctly. Given the names of your variables, this is unlikely to be a problem here.
Upvotes: 4
Reputation: 1679
You can do shifts and masks, or you can use the BitArray class: http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx
Example with BitVector32:
BitVector32 bv = new BitVector32(0);
var size = BitVector32.CreateSection(7);
var scale = BitVector32.CreateSection(3, size);
var precision = BitVector32.CreateSection(7, scale);
bv[size] = 5;
bv[scale] = 2;
bv[precision] = 4;
LINQPad output:
Upvotes: 7
Reputation: 726479
It is customary to number bits in a byte according to their significance: bit x
represents 2^x
. According to this numbering scheme, the least significant bit gets number zero, the next bit is number one, and so on.
Getting individual bits requires a shift and a masking operation:
var size = (v >> 0) & 7;
var scale = (v >> 3) & 3;
var precision = (v >> 5) & 7;
Shift by the number of bits to the right of the rightmost portion that you need to get (shifting by zero is ignored; I added it for illustration purposes).
Mask with the highest number that fits in the number of bits that you would like to get: 1 for one bit, 3 for two bits, 7 for three bits, 2^x-1
for x
bits.
Upvotes: 22
Reputation: 13196
Potayto, potahto.
You'd use shifts and masks to flatten out the undesired bits, like such:
byte b = something; // b is our byte
int size = b & 0x7;
int scale = (b >> 3) & 0x3;
int position = (b >> 5) & 0x7;
Upvotes: 5