从UInt32转换为Int32时保留位

问题描述 投票:0回答:1

我需要映射正整数值的坐标(行,列)。我通过以下方式实现.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 >= UInt32.MinValue And Me.Row <= UInt32.MaxValue / 2.Column也一样。

性能是关键。我不介意HashCode是什么。我相信从UInt32Int32的最佳转换不应改变存储器中的位。但是我很烦,因为这很可能正在发生,因为以下两行都返回相同的值:

    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

vb.net integer-overflow
1个回答
0
投票

[只要它们不溢出,就可以将两个整数从一种类型转换为另一种类型确实会返回相同的值(逐位为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

返回

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

移位操作<<>>确实会溢出而不会引发异常。溢出的位将丢失。

© www.soinside.com 2019 - 2024. All rights reserved.