从 UInt32 转换为 Int32 时保留位

Maintain bits when converting from UInt32 to Int32

我需要映射坐标(行,列),它们是正整数值。 我通过以下方式实现 .GetHashCode

    Public Function GetHashCode As Integer
            If _HashCode Is Nothing Then
                Const BitsPerValue As Integer = 32 \ 2
                Dim UnsignedCode As UInt32 = CType(Me.Row, UInt32) Xor (CType(Me.Column, UInt32) << BitsPerValue)
                _HashCode = CType(UnsignedCode, Int32)
            End If
            Return _HashCode.Value
    End Function
    Private _HashCode As Integer?

注意 Me.Row >= UInt16.MinValue And Me.Row <= UInt16.MaxValue .Column

也是如此

性能是关键。我不介意 HashCode 是什么。我相信从 UInt32Int32 的最佳转换不应该改变内存中的位。但我很困扰,因为这可能是正在发生的事情,因为以下两行 return 具有相同的值:

    Dim Unsigned123 As UInt32 = 123
    Dim Unsigned456 As UInt32 = 456
    Console.WriteLine("(UInt32) 123 Xor (456 << 16) = " & CType(Unsigned123 Xor (Unsigned456 << 16), UInt32))
    Console.WriteLine("(Int32) 123 Xor (456 << 16) = " & CType(Unsigned123 Xor (Unsigned456 << 16), Int32))

如何在不更改内存位的情况下进行转换?我知道 C# 中的 unchecked() 表达式在这里是理想的,但它不适用于 VB.Net.

我可以使用 BitConverter.ToInt32(BitConverter.GetBytes(UnsignedCode), 0) 但这不是贪心操作吗?

这基本上是 this one 的相反问题,我 想要 3392918397 变成 -902048899

预计将两个整数从一种类型转换为另一种类型会 return 相同的值(都是按位和 base10 的方式),只要它们不溢出。

考虑以下几点:

    Dim SignedMin As Int32 = Int32.MinValue
    Dim SignedMax As Int32 = Int32.MaxValue
    Dim UnsignedMin As UInt32 = UInt32.MinValue
    Dim UnsignedMax As UInt32 = UInt32.MaxValue

    Console.WriteLine("SignedMin As UInt32 = " & BitConverter.ToString(BitConverter.GetBytes(CType(SignedMin, UInt32)))) 'OverflowException
    Console.WriteLine("SignedMax As UInt32 = " & BitConverter.ToString(BitConverter.GetBytes(CType(SignedMax, UInt32)))) 'FF-FF-FF-7F
    Console.WriteLine("UnsignedMin As UInt32 = " & BitConverter.ToString(BitConverter.GetBytes(CType(UnsignedMin, UInt32)))) '00-00-00-00
    Console.WriteLine("UnsignedMax As UInt32 = " & BitConverter.ToString(BitConverter.GetBytes(CType(UnsignedMax, UInt32)))) 'FF-FF-FF-7F

    Console.WriteLine("SignedMin As Int32 = " & BitConverter.ToString(BitConverter.GetBytes(CType(SignedMin, Int32)))) '00-00-00-80
    Console.WriteLine("SignedMax As Int32 = " & BitConverter.ToString(BitConverter.GetBytes(CType(SignedMax, Int32)))) 'FF-FF-FF-7F
    Console.WriteLine("UnsignedMin As Int32 = " & BitConverter.ToString(BitConverter.GetBytes(CType(UnsignedMin, Int32)))) '00-00-00-00
    Console.WriteLine("UnsignedMax As Int32 = " & BitConverter.ToString(BitConverter.GetBytes(CType(UnsignedMax, Int32)))) 'OverflowException

Returns

SignedMin As UInt32 = OverflowException
SignedMax As UInt32 = FF-FF-FF-7F
UnsignedMin As UInt32 = 00-00-00-00
UnsignedMax As UInt32 = FF-FF-FF-FF

SignedMin As Int32 = 00-00-00-80
SignedMax As Int32 = FF-FF-FF-7F
UnsignedMin As Int32 = 00-00-00-00
UnsignedMax As Int32 = OverflowException

位移位操作 <<>> 会溢出而不会抛出异常。溢出的位丢失。