Microsoft KB Archive/58103

= How to Convert Unsigned Integer from Another Language to Basic =

Article ID: 58103

Article Last Modified on 11/21/2006

-

APPLIES TO


 * Microsoft QuickBasic 4.0
 * Microsoft QuickBASIC 4.0b
 * Microsoft QuickBasic 4.5 for MS-DOS
 * Microsoft BASIC Compiler 6.0
 * Microsoft BASIC Compiler 6.0b
 * Microsoft BASIC Professional Development System 7.0
 * Microsoft BASIC Professional Development System 7.1

-



This article was previously published under Q58103



SUMMARY
This article describes how to convert an unsigned integer value (returned from another language) to a Basic LONG integer, keeping the sign correct. This conversion is necessary because Basic does not support an unsigned integer data type.



MORE INFORMATION
Basic does not support an unsigned integer data type. However, there are times when a Basic program must accept an unsigned integer type returned after calling a function in a language such as C or assembly language, or after calling an MS-DOS interrupt.

If your other-language routine returns an unsigned integer to a Basic INTEGER data type, and if the value of the integer exceeds 32,767 (or 7FFF hex), it will print in Basic as a negative number, even though the CALLed routine meant to return a positive number in the range of 32,768 to 65,535 (passed as an unsigned integer). In such a case, your Basic program must convert the number to a positive number stored in a Basic long integer.

Basic stores both INTEGER and LONG data types as signed two's-complement numbers. In signed two's-complement format, the highest bit in the number is a a sign bit. When a Basic program is passed an unsigned integer from another language, and the number is in the range of 32,768 to 65,535, the highest bit will be set, causing Basic to treat the number as negative.

For more information, see pages 16-17 of &quot;Microsoft QuickBasic 4.0: Basic Language Reference,&quot; or see an assembly language book that discusses signed two's-complement data types.

Here is the simplest function to convert a 2 byte unsigned integer (stored in the Basic variable num%) to an unsigned number stored in a Basic LONG integer: num% = -1 PRINT unsignedlong&(num%)  ' Prints 65535 FUNCTION unsignedlong& (num%) IF num% < 0 THEN unsignedlong& = num% + 65536 ELSE unsignedlong& = num% END IF  END FUNCTION You can also convert an unsigned integer to a positive Basic LONG integer using bit manipulation as follows:  Check if the integer is positive or zero. If Basic already recognizes the number as positive or zero, then either use it as is, or assign it directly to a long integer and skip the next three steps. Otherwise, if the number (x%) is negative, then set the high bit to zero, as follows:

x% = x% AND &H7FFF&

  Assign the number to a long integer, as follows: y& = x%   Set the 15th bit (counting from bit zero) back to a one, as follows: y& = (y&OR &H8000&) The long integer (y&) now contains the correct positive integer that the other-language routine meant to pass back to Basic. 

Here is the simplest bit manipulation function to convert an unsigned integer to a positive Basic LONG integer: num% = -1 PRINT Unsigned&(num%)  ' Prints 65535 FUNCTION Unsigned&(param%) Unsigned& = &HFFFF& AND param% END FUNCTION

Example 1
The following program converts the unsigned integer stored in x% to a positive LONG integer stored in y&: x% = -1    ' -1 in two's complement is 65535 as unsigned integer IF x% < 0 THEN ' Set the 15th bit to zero (counting from bit 0): x% = (x% AND &H7FFF&) ' Assign it to a LONG integer: y& = x%  ' Set the 15th bit back to a one: y& = (y& OR &H8000&) ELSE y& = x% END IF PRINT y&  ' Prints 65535

Example 2
The following is a Basic code example that CALLs the INTERRUPT routine provided in QB.QLB or QB.LIB. This program accesses the PC system clock to get the number of clock ticks since midnight. It then calculates the number of seconds (in hundredths) since midnight.

To run the program in the QuickBasic editor, you must load the QB.QLB library, as follows: QB TIMEINT.BAS /L QB.QLB For Basic PDS 7.0 and 7.1 do the following instead: QBX TIMEINT.BAS /L QBX.QLB To compile and LINK the program, use the following: BC TIMINT.BAS; LINK TIMINT,,,QB.LIB; For Basic PDS 7.0 and 7.1 LINK as follows instead: LINK TIMEINT,,,QBX.LIB;

Code Example
DEFLNG A-Z ' $INCLUDE: 'qb.bi' CONST tps = 18.2064699073# ' tps is ticks per second DIM inregs AS RegType, outregs AS RegType DIM flag AS INTEGER, Previous AS LONG CLS WHILE 1 inregs.ax = 0 CALL INTERRUPT(&H1A, inregs, outregs) ' CX should never be larger than &H0017, so direct ' assignment is possible. ticks& = outregs.cx * &H10000 ' This IF statement is the part that accomplished the conversion. ' First, only convert if Basic thinks it's a negative number. IF outregs.dx < 0 THEN ' Set the 15th bit to zero (counting from 0) a2& = (outregs.dx AND &H7FFF&) ' Assign it to a LONG integer. ticks& = (ticks& + a2&) ' Set the 15th bit back to a one. ticks& = (ticks& OR &H8000&) ELSE ' Otherwise, just assign it to a long or use it 'as is'. ticks& = ticks& + outregs.dx    END IF     IF Previous > ticks& THEN BEEP ' It's midnight! Previous = ticks&

Previous = ticks& seconds# = ticks& / tps 'ticks per second

LOCATE 10, 10 PRINT &quot;Clock ticks since midnight: &quot;; PRINT ticks& LOCATE 11, 10 PRINT &quot;Seconds since midnight: &quot;; ' Print out the seconds to the hundredths place. PRINT USING &quot;######.##&quot;; seconds# WEND END

Additional query words: QuickBas BasicCom

Keywords: KB58103

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.