views:

757

answers:

2

I'm getting odd results in some VB6 code which I've narrowed to this:

Debug.Print Hex(&hEDB80000 + &h8300)

Shows EDB78300

That can't by right can it? Surely it should be EDB88300?

Am I going mad?

+14  A: 

Don't forget how negative numbers are expressed in binary, and that VB6 and VB.NET interpret numbers like &h8300 differently.

Because &hEDB80000 doesn't fit in 16-bits, VB interprets it as a long (32-bits). Because the high bit is set, VB6 knows it's negative.

Let's undo the two's complement (in a 32-bit world) to figure out the decimal value

(~&hEDB80000 + 1) = &h1247FFFF + 1 = &h12480000 = 306708480

since the sign bit was set, that's -306708480

Because &h8300 fits in 16-bits, VB interprets it as an integer (16-bits). Because the high bit is set, VB6 knows that it's negative.

Let's undo the two's complement (in a 16-bit world)

(~&h8300 + 1) = &h7DFF + 1 = &h7D00 = 32000

since the sign bit was set, that's -32000. When the addition happens, both values are considered to be longs (32-bits).

(-306708480) + (-32000) = -306740480

Let's put that back into two's complement hex

~(306740480 - 1) = ~(&h12487D00 - 1) = ~(&h12487CFF) = &hEDB78300

So &hEDB78300 is the correct answer.


Notes:

I personally thing the confusion happens because of the following:

&h0004000 is interpreted as  16384 // Fits in 16-bits, sign bit is not set
&h0008000 is interpreted as -32768 // Fits in 16-bits, sign bit is set
&h0010000 is interpreted as  65536 // Requires 32-bits, sign bit is not set

as mentioned in the other post, you can get around this by explicitly marking values as longs

&h0004000& is interpreted as  16384 
&h0008000& is interpreted as  32768 
&h0010000& is interpreted as  65536
Daniel LeCheminant
Can you elaborate on that? I'm not seeing how the result of anything negative plus a small positive number would end with the same small number. (Switching to base10... -1000 + 97 = 903, not something ending with 97.) His output ends with "8300", which is the number he added.
JMD
I've done the math in a hex calc and I get his expected result. I must not be seeing the forest for the trees.
JMD
@JMD: VB6 does things kind of weird, and interprets 0x8300 as a negative number, so it comes out strange
Daniel LeCheminant
@JMD: because the version ofg this answer you were reading was inaccurate. Daniel has since made an attempt at correcting it but seems to be overcomplicating it.
AnthonyWJones
AnthonyWJones
Daniel LeCheminant
+3  A: 

Fundementally because VB6 sees &h8300 as an integer having the value -32000. To get the results you were expecting you would need to explictly mark it as a Long:-

Debug.Print Hex(&hEDB80000 + &h8300&)

What your were doing was adding a Long to an Interger. To do that VB6 first extends the Integer to a Long, since &h8300 represents a negative number the Long it is converted to ends up with the value &hFFFF8300. Armed with that value you can see that the result returned by VB6 is correct.

FF + B8 = B7 with carry bit set
FF + ED + carry bit = ED
AnthonyWJones
Daniel LeCheminant
Corrected thanks
AnthonyWJones