从 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 是什么。我相信从 UInt32
到 Int32
的最佳转换不应该改变内存中的位。但我很困扰,因为这可能是正在发生的事情,因为以下两行 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
位移位操作 <<
和 >>
会溢出而不会抛出异常。溢出的位丢失。
我需要映射坐标(行,列),它们是正整数值。
我通过以下方式实现 .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 是什么。我相信从 UInt32
到 Int32
的最佳转换不应该改变内存中的位。但我很困扰,因为这可能是正在发生的事情,因为以下两行 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
位移位操作 <<
和 >>
会溢出而不会抛出异常。溢出的位丢失。