4

我在一些 VB6 代码中得到了奇怪的结果,我已经缩小到这个范围:

Debug.Print Hex(&hEDB80000 + &h8300)

显示EDB78300

那不可能吧?当然应该是EDB88300

我要疯了吗?

4

2 回答 2

15

不要忘记负数是如何用二进制表示的,并且 VB6 和 VB.NET 对 &h8300 之类的数字的解释不同。

因为 &hEDB80000 不适合 16 位,VB 将其解释为long(32 位)。因为设置了高位,VB6 知道它是负数。

让我们撤消二进制补码(在 32 位世界中)以找出十进制值

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

由于设置了符号位,那就是-306708480

因为 &h8300 适合 16 位,VB 将其解释为整数(16 位)。因为设置了高位,VB6 知道它是负数。

让我们撤消二进制补码(在16 位世界中)

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

由于设置了符号位,因此为-32000。当加法发生时,两个值都被认为是长整数(32 位)。

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

让我们把它放回二进制补码十六进制

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

所以&hEDB78300是正确的答案。


笔记:

我个人认为混乱的发生是由于以下原因:

&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

如另一篇文章中所述,您可以通过将值显式标记为 long 来解决此问题

&h0004000& is interpreted as  16384 
&h0008000& is interpreted as  32768 
&h0010000& is interpreted as  65536 
于 2009-02-18T21:25:32.803 回答
3

从根本上说,因为 VB6 将 &h8300 视为具有值 -32000 的整数。要获得您期望的结果,您需要明确地将其标记为 Long:-

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

您正在做的是将 Long 添加到 Interger 中。为此,VB6 首先将 Integer 扩展为 Long,因为 &h8300 表示负数,Long 转换为最终值 &hFFFF8300。有了这个值,您可以看到 VB6 返回的结果是正确的。

FF + B8 = B7 with carry bit set
FF + ED + carry bit = ED
于 2009-02-18T22:10:35.443 回答