vbGore Free Online RPG Engine

Revolutionizing Visual Basic ORPG Development
It is currently Sat May 18, 2013 6:47 pm

All times are UTC - 8 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 6:32 am 
Slave to the BB

Joined: Sat Feb 24, 2007 11:17 pm
Posts: 2704
Location: The Aussie Land
[SOLVED]

LSB and MSB were switched. Now my questions is, is there anyway to do copymemory backwards? and why is it so?
MSB: most significant byte


This is how i did it for anyone interested

Code:
Function GetInt(ByRef Source() As Byte) As Integer
Dim HiByte As Byte, LoByte As Byte

HiByte = Source(bPos)
LoByte = Source(bPos + 1)

  If HiByte And &H80 Then
    GetInt = ((HiByte * &H100&) Or LoByte) Or &HFFFF0000
  Else
    GetInt = (HiByte * &H100) Or LoByte
  End If
 
bPos = bPos + 2
 
End Function


Original Question
Quote:
I'm racking my brain on this one.

First of all i have a program that puts a 16bit unsigned integer into a byte array (can't change).

Then i have convert those 2 bytes into a signed integer in vb6.

Values are always smaller than 16,000. But when i use copymemory straight out i get wacky values, but when i join those bytes together in Windows Calculator i get the right number.


Top
 Profile  
 
 Post subject: Re: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 7:56 am 
=^.^= Kitty =^.^=

Joined: Tue Mar 20, 2007 10:46 pm
Posts: 1821
Location: Sydney Australia
Whacky values are normal.

A signed integer is calculated differently from an unsigned integer.


Top
 Profile  
 
 Post subject: Re: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 10:49 am 
Site Admin

Joined: Fri Jul 14, 2006 4:00 pm
Posts: 11230
Location: Washington
bakekitsune wrote:
Now my questions is, is there anyway to do copymemory backwards?


You mean un-copymemory? Like Ctrl+Z? :P

Copymemory works by taking pointer X and copying to pointer X + length, and setting the values to that in pointer Y to pointer Y + length. So if you want to do the reverse, just copy in the other way.

As for what you are doing, you are sending a ushort and reading it into VB6, which has no support of unsigned? If so, shouldn't you just be converting it to a long to preserve the value? I guess I am a bit confused since it depends on how you want the output value, since there are many ways to handle that bit.

But either way, reading the two bytes are going to preserve the bits, so if you want the same bits, you just need to use a bitwise OR:

Code:
GetInt = (HiByte << 8) | LoByte // this is what you already have


If you want to force a ushort (0 to 2^16) into the range of a short (-2^15 to 2^15), you are going to lose information if the bit is set (in which case it makes no sense to even send as a ushort):

Code:
GetInt = ((HiByte << 8) | LoByte) & ((2 << 16) - 1)


unless you convert it to a long:

Code:
GetInt = ((HiByte << 8) | LoByte // but of course, GetInt is actually a long now


Also, I am a bit confused on what the OR &HFFFF0000 is for there. You have a 16-bit integer, but you are OR-ing bits 17-32 onto it? Since all those set bits end up out of range, it is just a useless operation. So right now, you essentially have:

Code:
if the last bit on HiByte is set then
   GetInt = HiByte shifted over one byte, combined with LoByte, then OR'ing only bits out of range
else
   GetInt = exact same as above, but no OR at the end
end if


So unless I'm mistaken on what that last OR is doing, the whole operation could just be:

Code:
Function GetInt(ByRef Source() As Byte) As Integer
   GetInt = (Source(bPos) * &H100) Or Source(bPos + 1)
   bPos = bPos + 2
End Function


Top
 Profile  
 
 Post subject: Re: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 9:02 pm 
Slave to the BB

Joined: Sat Feb 24, 2007 11:17 pm
Posts: 2704
Location: The Aussie Land
Is it possible to go

CopyMemory Dest, Source + 1, -1 ? :P I dunno maybe if i did 1&.

vb6 has no support for unsigned integers. only unsigned bytes.

The first statement is more of just a security precaution incase if the uint ends up >= 32678. Which will bring back the signed integer value from a signed long, os i don't get an overflow error. Then vb will automatically convert that back to integer. Although i could probably just put exit sub, but its kinda there just incase.

For signed numbers as soon as you go past the limit it starts going backwards. A 3bit signed integer would go, 0 1 2 3 -4 -3 -2 -1. So to get -1 you would need 111 which is an unsigned value of 7 (the maximum possible) .That means to turn an integer > 32677 into an signed integer, you have to bitwise OR with FFFF on the left word to flip it.

You were correct on the second statement, but i will hopefully enlighten you with the first statement.

I will explain it in logical terms, because if i explained it in bitwise terms, only you would understand. :P

If the Last Bit of the Left-Most Bit = True, then the byte value must be >= 128 (or signed -128), but because it is the left-most bit, then the actual number must be > 32677, outside the range of a signed integer.

Bitshift 8 bits to the left using the the long of Hex100 (using the trailing & to declare it as long), making those 8 bits the most significant bits.

Lets say the value of the bytes were MSB=128 and LSB=255. This should give a Unsigned value of 33023.

That means for the first stage.

Attachment:
Untitled-1.gif


Then OR the 2 bytes together.

Attachment:
Untitled-2.gif


This number because of the bitshift using a long, now has 16 preceding 0's.

If you OR
33023
00000000000000001000000011111111

with
FFFF0000
11111111111111110000000000000000

you get....

11111111111111111000000011111111

Which is the Unsigned Long value of 4294934783.

Which is the Signed Long value of -32512. Which is a safe integer value that doesn't cause an overflow.

Yeh now that i look at it, its extremely pointless.


Top
 Profile  
 
 Post subject: Re: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 9:11 pm 
Site Admin

Joined: Fri Jul 14, 2006 4:00 pm
Posts: 11230
Location: Washington
That extra step would make sense if it was integral arithmetic, but with Boolean arithmetic, there shouldn't be any conversions taking place. If you tell it to OR a set of bits, it should set those bits, no matter the sign or even data type. This is why you can store literally any type as an array of bytes or signed bytes interchangeably without it having any affect on the results, since you are never performing integral arithmetic. You won't get any overflows because of this, either, which is why there is no need for bit masking.

Also, your base 10 values for the columns are a bit off on the chart. :P


Top
 Profile  
 
 Post subject: Re: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 9:29 pm 
Slave to the BB

Joined: Sat Feb 24, 2007 11:17 pm
Posts: 2704
Location: The Aussie Land
Ok thanks!

So your saying i should just remove the FFFF bitmask or the whole if statement? :D

Spodi wrote:
Also, your base 10 values for the columns are a bit off on the chart. :P



They are? Where? :?


Last edited by bakekitsune on Sun Oct 26, 2008 9:51 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 9:49 pm 
Site Admin

Joined: Fri Jul 14, 2006 4:00 pm
Posts: 11230
Location: Washington
bakekitsune wrote:
So your saying i should just remove the FFFF bitmask or the whole if statement? :D


The whole IF statement can go. Ignore sign and unsigned - this only matters in the final product, unless you were trying to preserve the sign/remove the sign and were converting to a smaller/larger integral type. From what I understand, you want to just take 16-bits unsigned, convert it to a byte array to send it, then convert it back to 16-bits (but signed this time). The 16th bit should never be set in this case because this would result in data loss since you can not convert back to the original sign due to lack of support by the language. So all you need is:

c = (high << 8) | low;

That's it. You can add a conditional in there to make sure the 16th bit is not set, because if it is, this means that the 16th bit was also sent, which means that it is impossible for you to (unless you convert to a 32-bit data type) recreate the original value. Because you are sending an unsigned integer, you can put this value into a long instead to preserve the data range, and still not have to worry about the sign.

Sign only matters in integral arithmetic. If you could safely assume these returned values were, for some reason, only used in Boolean arithmetic, it wouldn't matter what sign it was in at all. That's the beauty of Boolean arithmetic, and why machines are so efficient with it - given two sets of values, it only compares the nth bit to the nth bit. That is, no surrounding bits ever matter in Boolean arithmetic. If you want to set the 7th bit, it doesn't matter what any other bits are, or even the size of the integer. You could even easily make your own custom data types that contain billions of bits that perform Boolean arithmetic against each other with much ease, since all you would have to do is loop through each data type's memory and perform the operation one word at a time.

bakekitsune wrote:
They are? Where? :?


You have bytes on the range of 2 to 256, but it should be 1 to 128. Also, the 16th bit is actually 2^15, not 65536. Same with the 8th bit - it is actually 2^7.


Top
 Profile  
 
 Post subject: Re: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 9:57 pm 
Slave to the BB

Joined: Sat Feb 24, 2007 11:17 pm
Posts: 2704
Location: The Aussie Land
Oh ur right! oopsies! stupid cisco and their analogies... confuse the crap out of me.

Thanks!


Top
 Profile  
 
 Post subject: Re: Convert 2 bytes for Unsigned Integer to Signed Integer [Solv
PostPosted: Sun Oct 26, 2008 10:07 pm 
Site Admin

Joined: Fri Jul 14, 2006 4:00 pm
Posts: 11230
Location: Washington
No prob. I love working with binary. :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 8 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group