PowerBASIC programs process two distinct classes of data: variables and constants. A variable is allowed to change its value as a program runs. A constant's value is fixed at compile-time, and cannot change during program execution (hence, it remains constant). PowerBASIC supports four types of constants: string literals, numeric literals, string equates and numeric equates.
A string literal is simply a group of characters surrounded by quotation marks. It may optionally be followed by a TypeID of a single $ to specify ANSI characters, or a double $$ for wide, Unicode characters. If no TypeID is included, the default is ANSI characters. PowerBASIC will always make ANSI/WIDE conversions as needed, but it is best to specify it explicitly for efficiency. For example:
MyAnsi$ = "This is a string"$
MyWide$$ = "This is a UniCode string"$$
A string literal can include the double-quote character, simply by doubling the character within the string. For example:
A$ = "This is a ""string"""
Numeric literals represent numeric values. They consist primarily of the digits 0 through 9 and a decimal point. Negative values need a leading minus sign (-); a plus sign (+) is optional for positive values. The amount of precision you supply determines the internal representation (Integer, Long-integer, Quad-integer, Byte, Word, Double-word, Single-precision, Double-precision, Extended-precision, and Currency) which PowerBASIC will use in processing that literal value.
You can also force a literal value to be stored with a given precision by following the constant with one of the variable type-specifiers (%, &, &&, ?, ??, ???, !, #, ##, @, @@). This ability becomes very important when working with Currency and other floating-point numbers.
For example, the statement eVar## = 1.1 stores the Single-precision representation of 1.1 (which is 1.10000002384185791) in the Extended-precision variable eVar##. In order to store the exact quantity 1.1 in eVar##, you must follow 1.1 with the Extended-precision type-specifier (##). For example
DIM x1 AS EXT, x2 AS EXT
x1 = 1.1 ' Single-precision literal
x2 = 1.1## ' Extended-precision literal
a$ = STR$(x1,18) ' 1.10000002384185791
b$ = STR$(x1) ' 1.10000002384186
c$ = STR$(x2,18) ' 1.1
d$ = STR$(x2) ' 1.1
If a type-specifier does not follow a numeric constant, the following rules are used to determine the precision the value will be stored in:
If the value contains no decimal point and is in the range 0 to 255, PowerBASIC stores the value as a Byte.
If the value is an integer in the range -32,768 to 32,767, yet outside the range for Byte constants, PowerBASIC stores the value as an Integer.
If the value is an integer in the range 32,768 to 65,535, PowerBASIC will store the value as a Word.
If the value is an integer in the range -2^31 to 2^31-1 inclusive (about -2 billion to +2 billion), yet outside the range for Word constants, PowerBASIC stores the value as a Long-integer.
If an integer value is positive, exceeds the maximum value for a Long-integer, and still falls within the range for a Double-word, PowerBASIC will store the value as a Double-word.
If the value is an integer too large to fit in a Long or Double-word, but small enough to fit in a Quad integer, it will be stored as a Quad integer.
If the value contains a decimal point and has up to six significant digits, PowerBASIC stores it as a Single-precision floating-point.
A numeric constant with a decimal point and more than six significant digits, but less than 17, or a whole number too large to be a Quad-integer but small enough to fall within the range of Double-precision floating-point, is stored in Double-precision floating-point format. Larger values (with up to 18 significant digits) are stored in Extended-precision format.
For example:
345.1 ' A Single-precision constant
1.10321 ' A Single-precision constant
1.103213 ' A Double-precision constant
3453212.1234 ' A Double-precision constant
1112223.4445556667 ' An Extended-precision constant
When the sign of an Integer constant is not apparent (there is no type-specifier), PowerBASIC uses the following rules to determine whether to store the value as signed or unsigned:
If the number includes a type-specifier, the value will be signed or unsigned according to the type (specifically: Byte, Word and Double-word are unsigned; Integer, Long-integer, Quad-integer are signed).
If there is no type-specifier, and the number is a 16-bit quantity expressed as exactly 4 hexadecimal digits (or the number is a 32-bit quantity expressed as exactly 8 hexadecimal digits) and the most significant bit is set, the value is considered to be signed. All other hexadecimal constants are evaluated as unsigned. The same rules apply to 16 and 32 bit binary and octal literals.
Such signed hexadecimal values can be forced to evaluate as unsigned by adding an additional leading zero digit, or by adding a type-specifier suffix. This behavior is designed for compatibility with other BASIC dialects.
Some examples of these rules follow:
32767?? ' A Word constant (unsigned)
-40000 ' A Long-integer constant (signed)
32 ' A Byte constant (unsigned)
-32 ' An Integer constant (signed)
&H08000 ' A Word constant (unsigned)
&H8000 ' An Integer constant (signed)
&H8000& ' An Integer constant (signed)
&H08000& ' An Integer constant (signed)
&H80000000 ' Long-integer constant (signed)
&H80000000&& ' Long-integer constant (signed)
&H080000000 ' Double-word constant (unsigned)
&H80000000??? ' Double-word constant (unsigned)
This sequence of events allows PowerBASIC to make an intelligent decision about the constants in your program. Rather than arbitrarily making all ambiguous constant references signed (or unsigned), it tries to determine what type of constant you intended to use. You do not necessarily have to make a decision about the size of an integer constant, only whether it should be signed or unsigned. All you need to do to guarantee that a constant will be treated as an unsigned value is to place a leading zero in the number. You need not consider whether the number is a Byte, Word, or Double-word (as long as you do not exceed the largest Double-word value).
Integral constants in binary, octal, and hexadecimal
It is sometimes convenient to express integral values in number systems (bases) other than decimal (which is base 10). This is particularly true when expressing information that is binary in nature; for example, machine addresses. PowerBASIC allows you to specify integer data in Hexadecimal (base 16), Octal (base 8), and Binary (base 2) notation.
Hexadecimal constants consist of up to 16 characters, where each character is from the set 0 through 9 and A through F (and a through f), and must be preceded by &H. An additional (leading) zero can also be included to force the hexadecimal value to be treated as an unsigned value, or a suitable type-specifier can be added instead. The following are equivalent ways of specifying an unsigned hexadecimal value in the Double-word (DWORD) range:
A??? = &H0FFFFFFFF
A??? = &HFFFFFFFF???
Octal constants contain only the characters 0 through 7, can be up to 22 digits long, and must be preceded by &O, &Q, or simply &.
B = &Q7777
Binary constants contain only 0s and 1s, can be up to 64 digits long, and must be preceded by &B.
Each of the following constants represents the integer value 256 (decimal):
256 ~ &H100 ~ &O400 ~ &Q400 ~ &400 ~ &B100000000
Just as with decimal constants, a hexadecimal, octal or binary constant may have a type-specifier. You can use ?, ??, ???, %, &, && (Byte, Word, Double-word, Integer, Long-integer, Quad-integer) type-specifiers with constants in any number base.
If you do not use a type-specifier with these constants, the compiler will select the smallest integral type that will contain the number. When there is no type-specifier, PowerBASIC stores the value as unsigned, unless the most significant bit is a sign bit and the leading digit is not a zero. For example, &H8000 is signed, because its most significant bit is a sign bit (1000 0000 0000 0000), and its leading digit is non-zero. On the other hand, &H08000 is unsigned; although its most significant bit is a sign-bit (1000 0000 0000 0000), its leading digit is a zero.
You can use the VAL function to convert strings to numeric values. Such strings can contain decimal, hexadecimal, binary and octal numbers in string format. See VAL function for more info.
See Also