Microsoft KB Archive/189323

= How To Convert Between Signed and Unsigned Numbers =

Article ID: 189323

Article Last Modified on 7/15/2004

-

APPLIES TO


 * Microsoft Visual Basic for Applications 5.0
 * Microsoft Visual Basic 5.0 Learning Edition
 * Microsoft Visual Basic 5.0 Professional Edition
 * Microsoft Visual Basic 5.0 Enterprise Edition
 * Microsoft Visual Basic 4.0 Standard Edition
 * Microsoft Visual Basic 4.0 Professional Edition
 * Microsoft Visual Basic 4.0 32-Bit Enterprise Edition
 * Microsoft Access 95 Standard Edition
 * Microsoft Access 97 Standard Edition

-



This article was previously published under Q189323



SUMMARY
Visual Basic for Applications only supports signed 2- and 4-byte Integers, while other languages, such as C, support both signed and unsigned Integers. This article provides conversion functions between signed and unsigned 4-byte Integers and between signed and unsigned 2-byte Integers.



MORE INFORMATION
In VBA, the range of Integer values is from -32768 to +32767, and for Long values from -2147483648 to 2147483647. When making API calls or calling a DLL written in C, you may be requested to pass in or receive unsigned values in the range of 0 to 65535 or 0 to 4294967296. The conversion functions provided below convert an unsigned Integer to a Long and also from an unsigned Long to a Double for purposes of input and display or other calculations.

The four functions are:

UnsignedToLong

LongToUnsigned

UnsignedToInteger

IntegerToUnsigned

UnsignedToLong
The function takes a Double containing a value in the range of an unsigned Long and returns a Long that you can pass to an API that requires an unsigned Long.

LongToUnsigned
The function takes an unsigned Long from an API and converts it to a Double for display or arithmetic purposes.

UnsignedToInteger
The function takes a Long containing a value in the range of an unsigned Integer and returns an Integer that you can pass to an API that requires an unsigned Integer.

IntegerToUnsigned
The function takes an unsigned Integer from and API and converts it to a Long for display or arithmetic purposes. Declare Function MyAPI Lib "xxx" (Value As Long) As Long Dim uResult As Long uResult = MyAPI(UnsignedToLong(3300000000)) Debug.Print "Return Code: " & LongToUnsigned(uResult) In the above example, the MyAPI API accepts an unsigned Long as a parameter and returns an unsigned Long as a result code. Because VBA only understands signed Longs, the DECLARE statement uses signed Longs. The UnsignedToLong function converts a number outside the range of signed Long (but within the range of an unsigned Long) into a signed Long for purposes of calling the API. The LongToUnsigned function performs the opposite conversion.

Without these functions, the input argument would have to have been specified as a signed Long, in this case -994967296, and the return value would have to be displayed as a signed value, possibly also as a negative number and non-intuitive.

Step by Step Example
 Create a new VBA project.  Add the following code to a Module: Option Explicit

Private Const OFFSET_4 = 4294967296# Private Const MAXINT_4 = 2147483647 Private Const OFFSET_2 = 65536 Private Const MAXINT_2 = 32767

Function UnsignedToLong(Value As Double) As Long If Value < 0 Or Value >= OFFSET_4 Then Error 6 ' Overflow If Value <= MAXINT_4 Then UnsignedToLong = Value Else UnsignedToLong = Value - OFFSET_4 End If     End Function

Function LongToUnsigned(Value As Long) As Double If Value < 0 Then LongToUnsigned = Value + OFFSET_4 Else LongToUnsigned = Value End If     End Function

Function UnsignedToInteger(Value As Long) As Integer If Value < 0 Or Value >= OFFSET_2 Then Error 6 ' Overflow If Value <= MAXINT_2 Then UnsignedToInteger = Value Else UnsignedToInteger = Value - OFFSET_2 End If     End Function

Function IntegerToUnsigned(Value As Integer) As Long If Value < 0 Then IntegerToUnsigned = Value + OFFSET_2 Else IntegerToUnsigned = Value End If     End Function  Visual Basic only: Run the project and pause it.  Type the following in the Immediate/Debug Window: ?UnsignedToLong(3300000000) ?LongToUnsigned(-55) ?UnsignedToInteger(45000) ?IntegerToUnsigned(-3000)  You will get the following results:

-994967296

4294967241

-20536

62536



