Вот довольно безболезненный способ спускать длинный путь к int, просто извлекая 32-разрядные разряды младшего разряда без выброса исключения. Нет 64-битного деления, никаких блоков try/catch, просто бит-скручивание и одно сравнение.
Private Function CastLongToInt(x As Long) As Integer
Dim value As Integer = CType(x And &H7FFFFFFFL, Integer) ' get the low order 31 bits
' If bit 32 (the sign bit for a 32-bit signed integer is set, we OR it in
If (0 <> (x And &H80000000L)) Then
value = value Or &H80000000I
End If
Return value
End Function
Вот когда проще цветопередача — только бит вертел. Нет никаких сравнений. Мы просто захватить 2 16-разрядные тетрады и собрать их в конечное значение:
Private Function CastLongToInt(x As Long) As Integer
Dim hiNibble As Integer = &HFFFFL And (x >> 16)
Dim loNibble As Integer = &HFFFFL And x
Dim value As Integer = (hiNibble << 16) Or loNibble
Return value
End Function
отредактирован Примечание:
Другим вариантом было бы использовать обнуляемого целое (System.Nullable<int>
). В VB.Net, было бы что-то вроде этого:
Private Function TryCastLongToInt(x As Long) As Integer?
Dim value As Integer?
Try
value = CType(x, Integer)
Catch
' This exception intentionall swallowed here
End Try
Return value
End Function
Или, если понятие намеренно отлова и глотания исключений ошибки вы:
Private Function TryCastLongToInt(x As Long) As Integer?
If (x < Integer.MinValue) Then Return Nothing
If (x > Integer.MaxValue) Then Return Nothing
Return x
End Function
В любом случае, возвращаемое значение будет либо целочисленное значение или Nothing
, если 64-битное значение было вне домена 32-разрядного целого.
Какое значение вы хотите использовать VB.NET для длинного значения, большего, чем 'Int.MaxValue'? –
VB.NET делает, но вы должны собрать всю свою сборку таким образом. Наверное, не умная идея. –
@Cory: Это по умолчанию на C# - многие люди, похоже, в порядке с ним. Лично мне понравилась проверенная арифметика в большинстве случаев ... –