Packing and unpacking bits
-
I am trying to write a function in C# (VS2005/Net 2) which will pack and upack bits into a byte, short, integer and so on. As an example I have an Int32 in a file which is packed such that bits 0 thru 10 are one value and bits 11 thru 31 another. In another I have a short where the first 3 bits represent a value and so on thru. I have been playing around using bit shifting but it is not working. I am guessing that it may be something to do with the way the types are stored - I am no expert o nthis stuff but I wonder if they are little endian so the bit sequence is turned around by pairs. Any pointers would be much appreciated
Jon
-
I am trying to write a function in C# (VS2005/Net 2) which will pack and upack bits into a byte, short, integer and so on. As an example I have an Int32 in a file which is packed such that bits 0 thru 10 are one value and bits 11 thru 31 another. In another I have a short where the first 3 bits represent a value and so on thru. I have been playing around using bit shifting but it is not working. I am guessing that it may be something to do with the way the types are stored - I am no expert o nthis stuff but I wonder if they are little endian so the bit sequence is turned around by pairs. Any pointers would be much appreciated
Jon
ScruffyDuck wrote:
I have been playing around using bit shifting but it is not working.
Standard question #1: What do you mean by "not working"?
ScruffyDuck wrote:
wonder if they are little endian so the bit sequence is turned around by pairs.
The value is first read from memory into the CPU, then it's shifted, so it doesn't matter how it's arranged in memory.
--- b { font-weight: normal; }
-
ScruffyDuck wrote:
I have been playing around using bit shifting but it is not working.
Standard question #1: What do you mean by "not working"?
ScruffyDuck wrote:
wonder if they are little endian so the bit sequence is turned around by pairs.
The value is first read from memory into the CPU, then it's shifted, so it doesn't matter how it's arranged in memory.
--- b { font-weight: normal; }
By not working I mean that the answer I get is not the correct one e.g. I am expecting 12345 as an answer and I am getting 21436 so I think I am ending up with extracting the wrong bits.
Jon
-
By not working I mean that the answer I get is not the correct one e.g. I am expecting 12345 as an answer and I am getting 21436 so I think I am ending up with extracting the wrong bits.
Jon
Maybe that with a sample of the code (and of the file) you will make our lives far easier...:(:)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
-
By not working I mean that the answer I get is not the correct one e.g. I am expecting 12345 as an answer and I am getting 21436 so I think I am ending up with extracting the wrong bits.
Jon
Unless you actually show the code that you tried, the only thing that anyone can say about it is that it's wrong. I assume that the example that you showed was not an actual value that you are using, as they have totally different bit patterns? It would be more helpful if you showed some real examples of what you are using. Any information that you withhold is directly affecting the assistance that you can get.
--- b { font-weight: normal; }
-
Unless you actually show the code that you tried, the only thing that anyone can say about it is that it's wrong. I assume that the example that you showed was not an actual value that you are using, as they have totally different bit patterns? It would be more helpful if you showed some real examples of what you are using. Any information that you withhold is directly affecting the assistance that you can get.
--- b { font-weight: normal; }
OK apologies for not being very precise. The file I am dealing with is very large and the packed information forms a very small part of it. When extracted it has to go through another transformation. What I am trying to understand is generally how to write a function which will take a set of bits out of a larger set and return their value as an Integer. For example if I have 32 bits in a UInt32 then this is what I tried: public static UInt32 Dword (UInt32 data, int start, int end) { UInt32 result = data << (31-end+1); result = result >> (31 - end + 1 + start); return result; } I am sure the code is very poor with magic numbers and so on but if I take the example of cutting out bits 3 thru 7 inclusive then I left shift to remove bits 8 thru 31 then right shift until bit 3 is not bit 0. I have absolutely no experience of dealing with bit manipulation. Apologies again if I am not clear but it is because I really don't know what I am doing here :)
Jon
-
OK apologies for not being very precise. The file I am dealing with is very large and the packed information forms a very small part of it. When extracted it has to go through another transformation. What I am trying to understand is generally how to write a function which will take a set of bits out of a larger set and return their value as an Integer. For example if I have 32 bits in a UInt32 then this is what I tried: public static UInt32 Dword (UInt32 data, int start, int end) { UInt32 result = data << (31-end+1); result = result >> (31 - end + 1 + start); return result; } I am sure the code is very poor with magic numbers and so on but if I take the example of cutting out bits 3 thru 7 inclusive then I left shift to remove bits 8 thru 31 then right shift until bit 3 is not bit 0. I have absolutely no experience of dealing with bit manipulation. Apologies again if I am not clear but it is because I really don't know what I am doing here :)
Jon
Hi, both +1 terms should be dropped, as you can see from these simple cases: if you want all bits (so start=0, end=31) then no shifting should occur. if you want the LSB (start=end=0) then it should read (data<<31)>>31 if you want the MSB (start=end=31) then it should read (data<<0)>>31 When shifting one more in both directions, you actually loose the most significant bit of your bit field. :)
Luc Pattyn
-
OK apologies for not being very precise. The file I am dealing with is very large and the packed information forms a very small part of it. When extracted it has to go through another transformation. What I am trying to understand is generally how to write a function which will take a set of bits out of a larger set and return their value as an Integer. For example if I have 32 bits in a UInt32 then this is what I tried: public static UInt32 Dword (UInt32 data, int start, int end) { UInt32 result = data << (31-end+1); result = result >> (31 - end + 1 + start); return result; } I am sure the code is very poor with magic numbers and so on but if I take the example of cutting out bits 3 thru 7 inclusive then I left shift to remove bits 8 thru 31 then right shift until bit 3 is not bit 0. I have absolutely no experience of dealing with bit manipulation. Apologies again if I am not clear but it is because I really don't know what I am doing here :)
Jon
Instead of shifting the data back and forth to get rid of unwanted bits, use a bit mask. If you want bits 3 through 7, use a bit mask where those bits are set to one, and use the binary and operator (&) to clear the unwanted bits:
mask = 0x00f8; data = data & mask;
Then shift the data the three bits to place it at bit zero and up:data = data >> 3;
--- b { font-weight: normal; }
-
Instead of shifting the data back and forth to get rid of unwanted bits, use a bit mask. If you want bits 3 through 7, use a bit mask where those bits are set to one, and use the binary and operator (&) to clear the unwanted bits:
mask = 0x00f8; data = data & mask;
Then shift the data the three bits to place it at bit zero and up:data = data >> 3;
--- b { font-weight: normal; }
OK Thank you everyone - it is now working :)
Jon