I'm using a library call, setInstance(ByVal instance As UInteger), in my VB.NET code. The parameter I need to pass is an Integer. Is there anything I need to do to convert the integer parameter to an unsigned integer? The number is guaranteed to be positive and less than 10.
Like so...
Dim MyInt As Int32 = 10
Dim MyUInt As UInt32 = CUInt(MyInt)
setInstance(MyUInt)
CUInt or CType(x, UInt) allow converting a positive integer.
It throws an exception when x is negative.
To use Int as Uint, you can use some tricks:
dim bb() = System.BitConverter.GetBytes(myInt)
dim MyUint = System.BitConverter.ToUInt32(bb, 0)
Also with System.Buffer.BlockCopy for arrays.
If you configure the compiler to disable Check Integer Overflow (default for C#). Then you can use CUInt with negative values with no check - not exception.
You can call CUint to convert a variable to a UInteger.
Related
For example, I would like to assign &H80000000 to a 64-bit signed integer variable:
Dim a As Long = &H80000000
However, integer a has value &HFFFFFFFF80000000 instead of &H80000000.
I tried to call CULng to circumvent the sign-extension. Nonetheless, it says "Constant expression not representable in type 'ULong'". I conjecture this is because Visual Basic prohibits a negative integer to be assigned to an unsigned variable.
I am using Visual Basic 2010 (.NET Framework 4.0)
Dim a As Long = &H80000000L
Use the literal suffix L to tell the compiler that you intend this value to be a long literal. Otherwise, it's interpreted as a signed integer literal representing a negative value (-2147483648). Alternatively, you can use the suffix UI to denote an unsigned integer.
Example code:
Dim a As Long = &H80000000 ' Int32 literal -2147483648
Dim b As Long = &H80000000L ' Int64 literal 2147483648
Dim c As Long = &H80000000UI ' UInt32 literal 2147483648
Console.WriteLine(a.ToString("X")) ' FFFFFFFF80000000
Console.WriteLine(b.ToString("X")) ' 80000000
Console.WriteLine(c.ToString("X")) ' 80000000
Am using VS2010 VB.net
Dim Register As UInt64
Register = 12297264199100303880
If (Register And &H3FFF) = &H555 Then ' Get Overflow exception here
MsgBox("Done")
End If
Why is this happening and is there a work-around?
Your literal values are implicitly typed as long (Int64), since you didn't specify a type for them. I actually got the overflow on the assignment to Register, since the value given is too big for a long. To get this to work, just specify the type for your literal values, e.g. UL for unsigned long:
Dim Register As UInt64
Register = 12297264199100303880UL
If (Register And &H3FFFUL) = &H555UL Then
MsgBox("Done")
End If
Turning Option Strict On would be helpful, in this case. If you did, you would immediately see the problem. The problem is that the literals are interpreted as Integer (Int32) rather than ULong (UInt64). In order to force the literal to be interpreted as a ULong values, you need to add the UL type suffix:
Dim Register As UInt64
Register = 12297264199100303880UL
If (Register And &H3FFFUL) = &H555 Then ' Get Overflow exception here
MsgBox("Done")
End If
I fixed this by:
Dim DoneMask As UInt64 = &H3FFF
Dim Register As UInt64
Register = 12297264199100303880
If (Register And DoneMask) = &H555 Then ' Get Overflow exception here
MsgBox("Done")
End If
Apparently VB does better with explicit data types instead of a literal
I do not understand at all how to use TryCast in my code, but it is something I need to use for validating user input. I have done various searches and looked at various questions on here, but no one seems to actually say how to use it, and the MSDN website doesn't seem to help at all.
Function ValidateInput(Var_In As String) As Integer
If TryCast(Var_In, Integer) = Nothing Then
Return vbNull
Else
Return Var_In
End If
End Function
The error says that
The operand must be of reference type but Integer is of value type
What is the explanation of what I have done wrong?
TryParse doesn't accept more than 10 digits so for example, an input of "12345678901" won't be accepted. How do I fix this?
Let's try to understand the differences between TryCast, Convert and TryParse.
TryCast
This function will attempt to convert one object into another type, as long as it is a reference type.
Dim MyNewObject = TryCast(MyObject, MyReferenceClass)
If IsNothing(MyNewObject) Then
MessageBox.Show("Impossible to cast")
End If
Since Integer is a value type, it will not work, so we have to figure something out...
Convert
Convert Class on MSDN
From MSDN:
Converts a base data type to another base data type.
So we can try:
Dim myInt = Convert.ToInt32(MyObject)
The problem is that it will generate an exception InvalidCastException if it's impossible to do the conversion.
TryParse
This function is trying to convert a String into something you want. And it will not generate an exception:
Dim myInt As Integer = 0
If Not Integer.TryParse(MyString, myInt) Then
MessageBox.show("This is not an integer")
End If
Limitation
Converting a String into a Integer can sometimes be tricky... If the String represents a number that is greater or lesser than Integer.MaxValue and Integer.MinValue, you will end up with no conversion...
So you can go with a Double:
Double.TryParse(MyString, MyDouble)
Or personally, if you know that it will be a number, use Decimal:
Decimal.TryParse(MyString, MyDecimal)
See Decimals on MSDN
Decimal still has a Max and Min value, according to MSDN:
The Decimal value type represents decimal numbers ranging from positive 79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335. The Decimal value type is appropriate for financial calculations that require large numbers of significant integral and fractional digits and no round-off errors.
Convert.ChangeType
This one is also interesting, but is a bit weird...
You are attempting to perform TryCast against an Integer, which is a value type. TryCast works only on reference types, such as (but not limited to) a Class, Object, or String type.
If you are trying to convert the input parameter to an Integer, you might try one of the methods in the Convert class, such as Convert.ToInt32() or Integer.TryParse.
Instead of TryCast, use TryParse:
Function ValidateInput(Var_In As String) As Integer
Dim iNum As Integer
If (Integer.TryParse(Var_In, iNum)) Then
Return iNum
Else
Return vbNull
End If
End Function
Much better is to use TryParse:
Function ValidateInput(Var_In As String) As Integer
Dim num as Integer
If Not Integer.TryParse(Var_In, num) Then
Return vbNull
Else
Return num
End If
End Function
I'm late to the discussion, but if anyone lands here (like I did) looking for a quick & dirty solution, here a function I'm using for simple cell validation in a DataGridView control.
Function TryTypeFit(theString As String, theType As Type, ShowError As Boolean) As Boolean
Dim TempReturn As Boolean = False
Dim TempObject As Object
Try
TempObject = Convert.ChangeType(theString, theType)
TempReturn = True
Catch ex As Exception
' didn't work
TempReturn = False
If ShowError Then
Dim eMessage As String = "Error: Value must be castable to a " & CStr(theType.Name)
MsgBox(eMessage)
End If
End Try
100:
Return TempReturn
End Function
I have a value 123456789012345.89, which i am assigning to object type variable. By default, it is assigned as double object and lost precision (123456789012346) as value is too big for a double type. Is there any way i can get that value in object as decimal instead of double?
Dim obj As Object = 123456789012345.89
Dim deci As Decimal = obj
Console.WriteLine(deci)
Console.WriteLine(obj.ToString())
Assign the correct type by using 123456789012345.89D instead of 123456789012345.89:
Dim obj As Object = 123456789012345.89D ' now it's a Decimal
Dim deci As Decimal = DirectCast(obj, Decimal)
Console.WriteLine(deci)
I also strongly recommend to set Option Strict to On. Then you have to use DirectCast(or CType) to cast the object to decimal. But you gain compile time safety.
MSDN: Constant and Literal Data Types
I am having issues using VB.Net trying to convert a Long to a ULong.
I have tried many combinations and keep getting overflow errors.
I have a signed value of -2147483648, I know it will have a Ulong of 2151196588 once converted.
However I want to do this in a programmatic fashion because I am parsing values that can be negative and positive, but when the numbers are negative, they need to have the proper ulong value.
Note: Absolute values wont work, it needs to be a ulong for a true value.
Thank you.
If you mean reinterpret_cast<ulong>(long), then use the same technique:
<Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Explicit)> _
Public Structure LongULongUnion
<Runtime.InteropServices.FieldOffset(0)> Public l As Long
<Runtime.InteropServices.FieldOffset(0)> Public ul As ULong
End Structure
Sub Main()
Dim u As LongULongUnion
u.l = -2147483648L
Console.WriteLine(u.ul)
Console.ReadLine()
End Sub
But that gives 18446744071562067968 when converted.
You can use the BitConverter class:
Dim a As Int64 = -2147483648
Dim b = BitConverter.ToUInt64(BitConverter.GetBytes(a), 0)
Console.WriteLine(b.ToString) ' outputs: 18446744071562067968
Are you sure your intended value of 2151196588 is correct?
This is the easiest way to convert any Long to ULong:
Dim x As Long = -2147483648
Dim y As ULong = Not (CType((Not x), ULong)) ' = 18446744071562067968
I'm a C# programmer, so please correct me if I converted it to VB.NET incorrectly. My C# code was:
long x = -2147483648;
ulong y = ~((ulong)~x); // = 18446744071562067968
Basically you take the complement of the negative value, which is always a positive value. You can then safely cast it to ULong. Take the complement again and you have the same bit pattern cast to ULong.
Make sure you are converting your value to positive BEFORE you convert it to ulong, negatives are not in a ulong's value scope.
long: -9223372036854775808 to 9223372036854775807
ulong: 0 to 18446744073709551615