|
-
Jun 14th, 2007, 08:54 PM
#1
Thread Starter
Member
How to store 2 Half Bytes into 1 Byte?
Hello
I would like to encode a 2 16bit integer into a byte
than decode the 1 byte into 2 16bit integer ranges
something like this..
since both of the 16 bit integers only take up less half a byte 100% of the time.. I would like to be able to store them into a byte and be able to decode without any data loss...
like..
X = 3570
Y = 740
These are the ranges of X,Y 36x36 range
XArea
3570 / 36 = 99.1666667 which should be 100 because its overflowing the range
YArea
740 / 36 = 20.5555556 which should be 21 too because its overflowing the range.
Anyways I was thinking of using a signed byte to determine the decoding process accurately
like
if XArea is greater than YArea it would use positve numbers
if YArea is less than XArea it would use negivate numbers
and if both are equal to each other it would be 0 which would mean equality for X,Y.
Now Im trying to write both encode/decode in vb.net how should I do that?
vb Code:
Shared Function EncodeArea(ByVal X As Short, ByVal Y As Short) As SByte
Dim XArea As Short = Math.Ceiling(X / 36)
Dim YArea As Short = Math.Ceiling(Y / 36)
If XArea > 128 OrElse YArea > 128 Then Exit Function
If XArea > YArea Then
'Positves.. 1 to 127 i guess..
'Something I don't know goes here
ElseIf XArea < YArea Then
'Negiavtes.. -1 to -128 i guess
'Something I don't know goes here
Else
Return 0
End If
End Function
Shared Sub DecodeArea(ByVal Area As SByte)
Dim XMax As Short = 'Area And 127 idk decodedXArea
Dim YMax As Short = 'Area And -128 idk decodedYArea
Console.WriteLine("X Range MAX: " + XMax.ToString)
Console.WriteLine("Y Range MAX: " + YMax.ToString)
End Sub
-
Jun 14th, 2007, 09:05 PM
#2
Re: How to store 2 Half Bytes into 1 Byte?
I'm a bit confused on this. You suggest that these items take up one nibble (half a byte, believe it or not), which would be four bits, and would mean that your number must always be <=31, but then you talk about using 16 bit bytes, and values 1 to 127 which would fit in a byte, but certainly not in a nibble. Your example has a number quite a bit larger than 31.
What is the actual size of the item? You could pack two bytes into a short (two bytes), which is easily done using the << operator, but since I'm unclear on what the actual size of the number is, I'm not inclined to go any further just yet.
My usual boring signature: Nothing
 
-
Jun 14th, 2007, 09:15 PM
#3
Thread Starter
Member
Re: How to store 2 Half Bytes into 1 Byte?
Well
Both X and Y would always be less than 128.. even less than that tbh.. around 100 each they come in as shorts but after i divide them by 36 they are always less than 128.. and since byte holds 256 0-255 im pretty sure I can fit they both in... but i don't know how to decode em.. after that
So i have to pack 2 bytes into a short with bitwise operation
i cant pack 2 bytes which both are always less than half a byte into 1 byte?
Hey im kinda confused atm but I think if I change unsigned byte to signed byte i could retreive the other half of the byte no?
Ok screw the idea of making 2 half bytes into 1 byte how would I do 2 bytes into short and decode it?
i dont know.. atm i think i got it got..
vb Code:
Shared Function EncodeArea(ByVal X As Short, ByVal Y As Short) As Short
Dim XArea As Short = Math.Ceiling(X / 36)
Dim YArea As Short = Math.Ceiling(Y / 36)
If XArea > 255 OrElse YArea > 255 Then Return -1
If YArea And &H80 Then
Return ((YArea * &H100&) + XArea) Or &HFFFF0000
Else
Return (YArea * &H100) + XArea
End If
End Function
Shared Sub DecodeArea(ByVal Area As Short)
If Area = -1 Then Exit Sub
Dim XMax As Short = Area And 255
Dim YMax As Short = (Area And 65280) \ 256
Console.WriteLine("X Range MAX: " + XMax.ToString)
Console.WriteLine("Y Range MAX: " + YMax.ToString)
End Sub
Last edited by vb2dub; Jun 14th, 2007 at 10:13 PM.
-
Jun 15th, 2007, 09:38 AM
#4
Re: How to store 2 Half Bytes into 1 Byte?
Well, you have a slight misunderstanding here. While your values are less than half of what a byte can hold, that doesn't mean that you will be able to pack both of them into a byte in any meaningful way. The problem is that to represent a number less than 128, you will be using 7 of the 8 bits in the byte, which means that you actually need 14 bits to represent two such numbers. Therefore, you really need two bytes for this, but that's ok, because a Short IS two bytes.
So you have two shorts with these lines:
Dim XArea As Short = Math.Ceiling(X / 36)
Dim YArea As Short = Math.Ceiling(Y / 36)
You also did this check, which is quite a good thing to look for:
If XArea > 255 OrElse YArea > 255 Then Return -1
Now you have the two shorts that you know are both less than 255. This means that the high byte on each of them is 0, and all the information is contained in the low byte. To pack the two into a single short, choose one to be the high part and one to be the low part. I choose XArea to be the low part, and YArea to be the high. To pack them, do this:
Dim PackedShort as Short = ((YArea << 8) OR XArea)
What the << operator does is shift the bits by the stated number of places. Thus if your original YArea looked like 0000 0000 0010 01011 then YArea << 8 will look like 0010 01011 0000 0000, which is just what we want (writing out sixteen bits is pretty awful to read). We can then OR in the XArea, and end up with the YArea information in the high byte, and the XArea information in the low byte:
Example:
XArea = 0000 0000 0101 1100
YArea = 0000 0000 0011 1010
After doing YArea << 8:
YArea = 0011 1010 0000 0000
After doing YArea OR XArea
YArea = 0011 1010 0101 1100
In the code I posted above, I put it all into a new short variable, but you could just as easily use either YArea or XArea, and you might as well, because there is no advantage to adding a new variable that you will immediately return. In fact, you could change the line I suggested to:
Return ((YArea << 8) OR XArea)
And skip the intermediate step of putting the value anywhere.
To decode, you would unpack the values:
Dim XArea = (Area AND &H00FF)
Dim YArea = ((Area >> 8) &H00FF)
You shouldn't need to AND off the high byte for YArea, because shifting the bits down by eight will shift the low byte right out of existence, and the high byte should be filled with 0. However, I seem to remember that .NET does not always do that. I think that .NET will replicate whatever value is in the eight bit of the high byte. If all your values are lower than 128, then the high bit will always be 0, and you can skip the AND mask, which simplifies YArea to:
Dim YArea = Area >> 8
But if you are not certain that you have values between 0 and 128, then it would be safer to just mask you the high byte.
My usual boring signature: Nothing
 
-
Jun 15th, 2007, 03:38 PM
#5
Thread Starter
Member
Re: How to store 2 Half Bytes into 1 Byte?
ya I understand it for now.. but its like that in a week or so i'll forget it :@
-
Jan 7th, 2012, 02:10 PM
#6
Frenzied Member
Re: How to store 2 Half Bytes into 1 Byte?
why do you want to do this exactly?
here to ponder
-
Jan 8th, 2012, 07:16 AM
#7
Re: How to store 2 Half Bytes into 1 Byte?
@incidentals: this thread is from 2007. vb2dub hasn't posted since the beginning of 2008, so you probably won't get a response.
I'm sure there are uses for something like this. A similar example, where you want to store (for instance) 8 independent boolean values, comes up when making data structures. Instead of storing 8 32-bit integers whose values are each 00...00 or 00...01 and taking 32*8 = 256 bits, you could mash the booleans together into a single byte taking only 8 bits, where each bit corresponds to a different boolean.
Perhaps the OP wanted some small data compression. For instance, a field might only take values between 0 and 15, and rather than storing that field in a byte, you'd want to more optimally store it in a nibble. I'm just guessing, though.
The time you enjoy wasting is not wasted time.
Bertrand Russell
<- Remember to rate posts you find helpful.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|