How to zero-extend a signed integer in Visual Basic .NET - vb.net

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

Related

How to store a big number in a variable

Nothing works, tried ULong, integer, uint64, biginteger, decimal. how to store this number in the variable? Option strict on
error: Overflow
Dim Number_N As Integer = 115792089237316195423570985008687907853269984665640564039457584007908834671663
Dim Number_N As ULong = 115792089237316195423570985008687907853269984665640564039457584007908834671663
Dim Number_N As UInt64 = 115792089237316195423570985008687907853269984665640564039457584007908834671663
Dim Number_N As BigInteger = 115792089237316195423570985008687907853269984665640564039457584007908834671663
Dim Number_N As Decimal = 115792089237316195423570985008687907853269984665640564039457584007908834671663
You would use BigInteger but you can't represent a BigInteger as a literal as you can with other numeric data types because it's not part of the language. You would have to represent the number in a String literal and call BigInteger.Parse:
Dim Number_N = BigInteger.Parse("115792089237316195423570985008687907853269984665640564039457584007908834671663")

assign hex values to variables according to its data types in visual basic .net

I'm aware that my question is similar with this question: Hex-Value in Visual Basic
but what I want to ask is a little more detail. My question is:
how do I assign a hex value to a variable according to it's data type in VB?
for example these are ways to assign hexes that i know:
Dim arr_ui as UInteger() = {&HABCDEF01UI, &HABCDEF01UI} '32 bit unsigned integer
Dim arr as Integer() = {&HABCDEF01, &HABCDEF01} '32 bit signed integer
Dim arr_64 as Int64() = {&HABCDEF01&, &HABCDEF01&} '64 bit signed integer
so that brings back to my question, how to assign these hexes:
- unsigned 64 bit integer
- signed and unsigned 16 bit integer
- signed and unsigned 8 bit integer
thanks in advance
' unsinged 64 bit integer
Dim uLong As ULong = &H123UL
' singed and unsigned 16 bit integer
Dim uShort As UShort = &H123US
Dim sShort As Short = &H123S
' signed and unsiged 8 bit integer:
' byte and signed byte won't have a suffix in VB.NET.
Dim aByte As Byte = &H12
Dim aSByte As SByte = &H11
since jmcilhinney does not want to claim his credit, the answer is here folks https://msdn.microsoft.com/en-us/library/s9cz43ek.aspx
here are some examples:
Dim a As Short = &H8000S -- 16 bit signed
Dim b As UShort = &H8000US -- 16 bit unsigned
Dim c As Short = &H8000I -- 32 bit signed
Dim d As UShort = &H8000UI -- 32 bit unsigned
Dim e As Short = &H8000L -- 64 bit signed
Dim f As UShort = &H8000UL -- 64 bit unsigned
alternate method:
Dim g As Short = &H8000% -- 32 bit signed
Dim h As Short = &H8000& -- 64 bit signed

How to store a two's complement number in a long

I am converting a VB6 application to VB.net. The application uses an existing C library I can't change.
The Problem: I am expecting a value around -180 or 180. The times that I expect 180, it works. But when I expect -180, I get the value 4294967117. This seems like the C library is returning a 2's complement number, but I don't know how to treat it.
This is the VB6 code that works:
Dim tmp As Long
If GetVal(VAL_A1, tmp) = ERR_VAL_NA Then
lblAngle(0).Caption = "na"
Else
lblAngle(0).Caption = tmp
End If
This is the VB.net code that does not work:
If GetVal(VAL_A1, tmp) = ERR_VAL_NA Then
txtBoxPhaseAngle1.Text = "na"
Else
txtBoxPhaseAngle1.Text = Convert.ToDouble(tmp)
End If
I have also tried:
txtBoxPhaseAngle1.Text = Convert.ToInt32(tmp)
txtBoxPhaseAngle1.Text = tmp
EDIT :
How I declare the C function:
Declare Function GetVal Lib "Z:\Devel\RelayAPI\Debug\RelayAPI.dll" (ByVal what As
Integer, ByRef val As Long) As Byte
Snippets from the GetVal function in the C code:
BYTE __stdcall GetVal(WORD what, long *val){
DWORD relaydate;
BYTE tmpb;
DWORD tmpd;
long tmp;
...
switch(what){
case VAL_A1:
tmpb=RelayAPI_Scaled;
if(tmpd<6){
*val=(short)((WORD)mon[38]+((WORD)mon[39]<<8));
}else{
*val=(short)((WORD)mon[32]+((WORD)mon[33]<<8));
}
break;
break;
}
When upgrading from VB6, you need to be aware that some data types have changed. In VB6, an Integer is 16-bits, and a Long is 32-bits. In VB.NET, though, an Integer is 32-bits and a Long is 64-bits.
In the C function, you have long *val, and a C long is "at least 32-bits" according to spec, so presumably your C-function is returning a 32-bit integer. However, VB.NET now believes that it's a Long (64-bit) value, and interprets it as such -- 4294967117 instead of -180.
If you change your VB.NET declaration of the val parameter to ByRef val As Integer, you will probably see the correct return value.

Visual Basic.Net Converting a Long to a Ulong

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

How to pass integer as unsigned parameter in VB.NET?

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.