Dot-Net
如何在沒有OverflowException的情況下將無符號整數轉換為有符號整數
我希望能夠將高值無符號整數(使用最高位的值)轉換為有符號整數。在這種情況下,我不在乎該值是否高於有符號整數類型的最大值。我只是希望它轉換為任何位值表示為有符號整數。換句話說,我希望它會產生一個負數。
但是,對於 VB.NET,該
CType操作不能以這種方式工作(或任何其他轉換函式,如CShortandCInteger)。當您嘗試轉換高於所需有符號類型最大值的無符號值時,它會拋出一個OverflowException而不是返回一個負數。例如:Dim x As UShort = UShort.MaxValue Dim y As Short = CShort(x) ' Throws OverflowException同樣值得一提的是,該
DirectCast操作不能用於在有符號和無符號類型之間轉換值,因為這兩種類型都不繼承或實現另一個。例如:Dim x As UShort = UShort.MaxValue Dim y As Short = DirectCast(x, Short) ' Won't compile: "Value of type 'UShort' cannot be converted to 'Short'我已經想出了一種方法來做我想做的事,但這似乎不必要地難看。這是我如何讓它工作的:
Dim x As UShort = UShort.MaxValue Dim y As Short = BitConverter.ToInt16(BitConverter.GetBytes(x), 0) ' y gets set to -1就像我說的那樣,這行得通,但是如果在 VB.NET 中有更簡單、更清潔的方法,我很想知道它是什麼。
如果您經常使用它,那麼持續使用
BitConverter會有點不方便——尤其是在性能方面。如果那是我,我會非常想在 C# 中添加一個可以進行直接轉換的實用程序庫(通過unchecked,儘管unchecked通常是 C# 中的預設值*)*,並為此引用該庫。另一種選擇可能是濫用“聯合”結構;以下應該很容易轉換為VB:[StructLayout(LayoutKind.Explicit)] struct EvilUnion { [FieldOffset(0)] public int Int32; [FieldOffset(0)] public uint UInt32; } ... var evil = new EvilUnion(); evil.Int32 = -123; var converted = evil.UInt32;IE
<System.Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Explicit)> Structure EvilUnion <System.Runtime.InteropServices.FieldOffset(0)> Public Int32 As Integer <System.Runtime.InteropServices.FieldOffset(0)> Public UInt32 As UInteger End Structure ... Dim evil As New EvilUnion evil.Int32 = -123 Dim converted = evil.UInt32
我認為最簡單的方法如下:
Public Function PutSign(ByVal number As UShort) As Short If number > 32768 Then 'negative number Return (65536 - number) * -1 Else Return number End If End Function