【问题标题】:VB.NET code returning different result than C# codeVB.NET 代码返回的结果与 C# 代码不同
【发布时间】:2012-04-20 07:57:29
【问题描述】:

以下 C# 代码给出结果“228452386”

UInt32 a;

int k = 0;

a = 0x9E3779B9;

a += (UInt32)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));

上述代码运行后,“a”包含“228452386”。

但VB.NET 中的以下相同代码会导致“算术运算导致溢出”。基本上最后一条语句是返回值“1868983913”,所以会产生运行时错误。

Dim a As UInt32

Dim k As Integer = 0

a = &H9E3779B9UI

a += CUInt(AscW(url(k + 0)) + (AscW(url(k + 1)) << 8) + (AscW(url(k + 2)) << 16) + (AscW(url(k + 3)) << 24))

请注意上面代码中的变量“url”可以是任意字符串,两个代码都是一样的。

当我在 C# 和 VB.NET 中运行以下语句时,它们都返回相同的值

C#

(UInt32)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24))

VB.NET

CUInt(AscW(url(k + 0)) + (AscW(url(k + 1)) << 8) + (AscW(url(k + 2)) << 16) + (AscW(url(k + 3)) << 24))

两个语句都为“url”“info:microsoft.com”返回值“1868983913”。但是,当我使用 a += ......... 运行完整语句时,VB.NET 会出错,而 C# 返回值“228452386”。

【问题讨论】:

标签: c# vb.net bit-manipulation runtime-error


【解决方案1】:

你有一个溢出,因为你添加的两个数字相加的结果大于 UInt 中的大小。

得到的数字是一个 33 位的数字,UInts 只适合 32 位。

  • 在 C# 中,最高有效位仅被切掉,保留适合 UInt 的 32 位。 (这个新值不是添加数字的实际结果。)
  • 在 VB.NET 中,您会收到一个异常,指出该数字不适合。

VB.NET 编译器(或 VS)允许您关闭这种溢出检查,以便 VB.NET 在这种情况下表现得像 C#。

【讨论】:

    【解决方案2】:

    VB.NET 会自动插入溢出测试,而 C# 不会。等效的 C# 代码是:

    UInt32 a;
    int k = 0;
    a = 0x9E3779B9;
    checked{
        a += (UInt32)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));
    }
    

    编辑:更改代码示例以符合已编辑的问题。

    【讨论】:

    • 基本上我想要基于 C# 代码的 VB.Net 等效代码。
    • 我没有找到 VB 的等效“未选中”关键字。 (不知道是否有。)但是您可以为您的 VB.NET 应用程序打开溢出检查,如下所述:stackoverflow.com/a/4515123/19594
    • 请检查我上面的编辑,因为我已经添加了更多信息。
    【解决方案3】:

    使用以下 VB.NET 代码:

        a += CUInt(AscW(url(k + 0))) + CUInt((AscW(url(k + 1)) << 8)) + CUInt((AscW(url(k + 2)) << 16)) + CUInt((AscW(url(k + 3)) << 24))
    

    AscW 返回一个整数(有符号),而你需要的是无符号的。

    编辑

    这行得通:

        Dim a As Int64
        Dim result As UInt32
    
        Dim k As Integer = 0
    
        Dim url As String = "info:microsoft.com"
    
        a = &H9E3779B9UI
    
        Dim a1 As UInt32 = 0
        Dim a2 As UInt32 = 0
        Dim a3 As UInt32 = 0
        Dim a4 As UInt32 = 0
    
        a1 = AscW(url(k + 0))
        a2 = AscW(url(k + 1)) << 8
        a3 = AscW(url(k + 2)) << 16
        a4 = AscW(url(k + 3)) << 24
    
        a = (a + a1 + a2 + a3 + a4) And &HFFFFFFF
        result = Convert.ToUInt32(a)
    

    【讨论】:

    • 我在使用上述语句时遇到了同样的错误,因为它也给出了值“1868983913”,如我上面的原始问题所述。
    • 它在我的电脑上返回了相同的值,你用哪个字符串作为 url?
    • 请检查我上面的编辑,因为我已经添加了更多信息。
    猜你喜欢
    • 2020-02-15
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多