2. Data Representation
This chapter describes the various ways to comprehend and represent information.
Constants versus variables
Section titled “Constants versus variables”Data can be viewed from two distinct perspectives and within those perspectives there are several variations. The first approach to data representation categorizes the data as either a constant or variable. Constants are fixed values and cannot change. Variables are named values that can change.
Examples of constants
Section titled “Examples of constants”- "Hello"
- a string constant of 5 characters containing the ASCII print characters for the word Hello
- ""
- a string constant of 0 characters (null)
- QUO
- a string constant containing the double-quote character (")
- 123
- a numeric constant with the integer value 123
- 123.456789
- a numeric constant with the fixed point value 123.456789
- .123E-110
- a numeric constant with the floating-point value (scientific notation) .123 to the -110 power of 10
- $20$
- a hexadecimal string constant whose value is equivalent to a decimal 32 or a space character
Examples of variables
Section titled “Examples of variables”- A$
- a string variable with a possible length of 0 - 65000 bytes
- A
- a numeric variable with the ability to hold numbers from +/-.99999999999999E-114 to +/-.99999999999999E+141 with up to 14 digits of precision
- A%
- a numeric integer variable with the ability to hold integers from -2147483648 to +2147483647
- DEC(A$)
- a numeric variable representing the decimal equivalent of the binary value in A$
- BIN(A,5)
- a string variable representing the binary equivalent of the numeric variable A in 5 bytes
The above examples do not demonstrate all possibilities. Other options appear in Chapter 6, Thoroughbred Basic Language Overview.
Conventions for naming variables
Section titled “Conventions for naming variables”The rules governing the names of variables are:
-
String variables all end in a dollar sign ($).
-
Numeric integer variables all end in a percent sign (%).
-
Numeric variables do not require a suffix.
-
Long variable names allow up to 33 characters in the name (exclusive of the dollar sign for string variables or the percent sign for integer variables).
-
Long variable names must start with an uppercase alphabetic character (A-Z). The remaining characters can be any combination of uppercase alphabetic characters, numeric characters, and the underscore character. For example:
THIS_IS_A_VALID_STRING_NAME$
THIS_IS_A_GOOD_NUMERIC_NAME
U_CAN_USE_NUMBERS_2_IN_NAMES
Short variable names contain 1 or 2 characters (exclusive of the dollar sign for string variables). The name must start with an uppercase alphabetic character (A-Z) and if a second character is needed, it must be numeric. (Integer variables, e.g. C%, are not available in release levels prior to 8.1.B2.) For example:
- A$, A1$, A2$, A9$, Z9$ are all valid string variable names
- A, A1, A2, A9, Z9 are all valid numeric variable names
- A%, A1%, A2%, A9%, Z9% are all valid integer variable names
Numeric versus string
Section titled “Numeric versus string”The second approach to data representation differentiates between numeric and string. The above examples of constants and variables indicate which is numeric and which are string data. There are very few instances where a constant is required and a variable not allowed, or the reverse. The more significant differentiation occurs between numeric and string data.
Numeric data
Section titled “Numeric data”Numeric data is a term used to describe numbers as opposed to alphabetic or alphanumeric data. In mathematics, the term decimal refers to base-10 numbers, binary to base-2, octal to base-8, hexadecimal to base-16, etc.
In Thoroughbred Basic, as in most versions of BASIC, decimal is the only valid form for numeric data. Binary, octal, and hexadecimal numbers are treated as string data. Numeric data can contain up to 14 digits and are limited to the range of numbers between +/- .99999999999999E-114 and +/-.99999999999999E+141. Valid numbers may contain the following:
- Digits 0 through 9.
- None or one decimal point.
- A leading + or - (+ is assumed if no sign is shown).
- The letter E followed by an integer value in the range of -114 to +141 (+ is assumed) representing a power of 10.
Commas are not valid in numbers. When converting a string to numeric, Thoroughbred Basic ignores spaces in the string. The following list shows some examples of valid numbers:
123.45
- 123.45E+0
.12345E3
+12345
The descriptions listed below are arranged in approximate ascending order. Each description is a subset of the next or is of equal or lesser (not greater) importance.
Numeric Data Types
- Integer
- a positive or negative, real, base-ten number with no significant digits to the right of any decimal point. The range of integers is +99999999999999 to -99999999999999.
- Fixed Point
- a positive or negative, real, base-ten number with significant digits to the right of a decimal point. The range of fixed-point numeric data is +/-0.99999999999999 to +/-99999999999999.0.
- Floating Point
- a positive or negative, real, base-ten number that is represented in exponential form: 12345 is represented as .12345E+5 and .00001 is represented as .1E-4. The range for floating point is +/-0.99999999999999E-114 to +/- 0.99999999999999E+141.
- Array
- a table of numeric data (Integer, Fixed Point, or Floating Point) with up to 3 dimensions, requiring integer subscripts to access the individual table entries. The maximum number of total entries in the array cannot exceed 65000 entries. In an I/O directive, you can use [ALL] as the subscript of an array to specify all elements of the array.
- Numeric Expression
- a numeric function, numeric constant, or arithmetic expression whose result is numeric data. Unless otherwise noted, numeric expressions can be used wherever numeric data are required.
- Numeric data
- can be manipulated with mathematical statements and arithmetic operators. The following
directives control the environment in which numeric data are manipulated. These directives also control the number of significant digits to be maintained when numeric data are moved or formatted into a string for printing.
Numeric Data Directives
- PRECISION
- This directive determines the number of significant digits to be maintained to the right of the decimal point. PRECISION 4 sets that number to 4. The default is 2 and is set when a Thoroughbred Basic program performs a clearing function (e.g., LOAD, END, CLEAR, or BEGIN). The range of valid values is numeric integers from 0 through 14.
- FLOATING POINT
- This directive has the same effect as PRECISION 14.
Rounding
Rounding occurs whenever numeric data are moved or manipulated in such a way that the resulting numeric variable contains fewer significant digits than the numeric data it is to contain. A simple way to show this to enter the following sequence of commands in Thoroughbred Basic Console Mode:
PRECISION 2
PRINT .05*.1
PRECISION 3
PRINT .05*.1
The first PRINT statement produces .01 (the result of .05*.1 rounded to 2 decimal places). The second PRINT statement produces .005 (displaying 3 decimal places). The actual arithmetic operation is performed using the number of significant digits actually present in the numeric values, with the result adjusted based on PRECISION and FLOATING POINT settings.
Order of Precedence
Numeric data are worked upon through the use of numeric functions and operators. Arithmetic operations are performed in the following order:
1 Parentheses, innermost first
2 Then left to right, all exponential
3 Then left to right, all multiplication and division with equal priority
4 Then left to right, all addition and subtraction with equal priority
5 Then left to right, all relational operators ( < >, =, <=, >=, <, >, LIKE) with equal priority
6 Then left to right, all logical operators (AND, OR) with equal priority
All operators are described below:
Operators in Conditions
- =
- Equal to
- Subtraction or negative value
- >
- Greater than
- <
- Less than
- >= or =>
- Greater than or equal to
- <= or =<
- Less than or equal to
- <> or ><
- Not equal to
- LIKE string
- Partial equality
- ( )
- Grouping
- AND
- Logical AND (both true)
- OR
- Logical OR (either true)
LIKE wildcards
- Matches any characters (0 or more)
- ?
- Matches a single character
- [A-Z]
- Matches a range for a single character
- [AGCF]
- Matches a single character in the list
- [wildcard]
- Matches the wildcard character
Operators Used in Arithmetic Functions
- ( )
- Parentheses to indicate priority of calculations
- ^ or **
- Exponentiation (requires a positive integer exponent)
- Multiplication
- /
- Division
- +
- Addition or positive value
- Subtraction or negative value
Boolean Operators
Relational Operators If the relation is true, the result is 1; otherwise, the result is 0.
- Logical Operators
- The result of AND is 0 if either or both of its operands are 0; otherwise, the result is one 1. The result of OR is 0 if both of its operands are 0; otherwise, the result is 1. If more than one logical operator appears in a statement, and Thoroughbred Basic determines the result after evaluating the first operand, Thoroughbred Basic skips the evaluation of the second operand.
Example
00010 LET A=0, B=0, C=5, D=-4, E=7, F=200020 LET VALUE=A+C OR B ;VALUE IS 100030 LET VALUE=A AND B ;VALUE IS 000040 PRINT 1 + (C AND E) ;PRINTS 200050 LET VALUE=A=B ;VALUE IS 100060 PRINT 10 + (D>F OR E>C) ;PRINTS 1000070 IF A THEN GOTO 1000080 LET VALUE=A$ LIKE "?PSD"Any numeric syntax that is accepted between IF-THEN can be used as a valid numeric expression anywhere a number is expected or allowed.
Examples of Numeric Functions
- ABS(n)
- the absolute value (positive) of a number, n
- CDN
- the current system date and time in SQL date numeric format
- INT(n)
- the integer portion of a number, n
- FPT(n)
- the decimal portion (fractional part) of a number, n
- LEN(str)
- the length, in bytes, of a string, str
- MOD(n1, n2)
- the remainder obtained when a number, n1, is divided by n2
- NUM(str [,ERR=line-num])
- converts a string to numeric data with error detection if not truly numeric (spaces are ignored)
- POS(str1 operator str2)
- finds the character position within a string, str2 based on the operator (e.g., =,<) and str1
- RND(n)
- a random number from 0.0 to 1.0 based on seeding specified by a number, n
- SIN(n)
- returns the trigonometric sine of angle n (n is in radians)
- This
- is not a complete list, but it gives an example of the diversity of numeric functions available within
Thoroughbred Basic. Besides those mentioned above, the programmer could define additional numeric functions. For more information, please refer to the description of the DEF FN directive.
String data
Section titled “String data”String data are all data that are not numeric data. A string variable is limited to a total length of 65000 bytes. Each byte in the string data can contain any of the 256-character possibilities. Caution should be taken, however, when dealing with string data that contain the following:
- Unprintable characters
- Special file terminators
- Record terminators
- Field separators
- Communication sensitive characters
In general, string data contain characters ranging from $20$ (hexadecimal for a space) through $7E$. This represents all numeric, upper and lowercase alphabetic, and the standard English punctuation characters.
String data is the only valid format for the communication of data. Numeric data must be converted to string data format before it can be printed. In many cases, numeric data must also be converted to string data before it can be stored or saved.
The descriptions below are arranged in approximate ascending order. Each description is a subset of the next or is of equal or less (not greater) importance.
String Data Types
- Substring
- a portion of a string variable using the format:
**STRING$ (**starting-byte [,number-of-bytes])
If the number-of-bytes is not specified, the substring ends with the last byte of the string.
- Array
- a table of string data with up to 3 dimensions. Array specifications require integer subscripts to access the individual table entries. Each table entry can vary in length, and the array can contain up to 65536 total entries. In an I/O directive, you can use [ALL] as the subscript of an array to specify all elements of the array.
- String Expression
- a concatenation of string variables and string constants to form a single series of characters. Unless otherwise noted, string expressions can be used wherever string data is required. For example:
TOWN_NAME$ + “,” + STATE_ABBREVIATION$ + STR(ZIP_CODE:“BB00000”)
The + (plus sign) is the concatenation character. The example above creates a single string containing the format for the last line of a street address. STR converts numeric data to string data format and will be covered later.
Besides the concatenation shown above, string data can be presented in a variety of forms through the use of several logical functions. As with numeric data, the programmer also has the ability to define specific string functions within a program (see the description of the DEF FN directive). Add to these the large variety of standard system variables in string data format, and it becomes easy to see that Thoroughbred Basic offers an excellent range of tools for program development. Below are several examples of string functions and system variables, which are in string data format.
Examples of String Functions
- AND(str1,str2)
- returns the logical AND of all bits in two strings, str1 and str2, bit for bit
- BIN(n1,n2)
- converts a base-10 decimal number, n1, into a base-2 binary number in the number of bytes specified by n2
- CVT(str,n)
- edits a string, str, based on the value in n to do such things as suppress extra spaces and tabs, align left or right, change uppercase to lowercase (or the reverse), and several other text editing functions
- DAY
- returns the system date in the format MM/DD/YY or a different format depending upon system specification for the installation
- IOR(str1,str2)
- returns the logical OR of all bits in two strings, str1 and str2, bit for bit
- NOT(str)
- returns the logical inverse of a string, str, bit for bit
- STR(n:str)
- returns a number, n, in string data format according to the contents of the editing mask contained in a string, str
- SYS
- returns the coded value for the release level of Thoroughbred Basic and its operating system environment
The proper understanding of numeric and string variables and functions can simplify data manipulation and presentation. For example, a common task is using the numeric function TIM to display the system time in the format HH:MM:SS. TIM is in 24-hour and decimal hour format. The following sequence of instructions provides the desired result:
PRECISION 6PRINT STR(INT(TIM):"#0") + ":" + STR (INT (FPT (TIM) *60):"00")+":"+STR(INT(FPT(TIM*60)*60):"00")If TIM is equal to 8.331667 then the PRINT statement displays 8:19:54 when executed. The logic of this string expression is:
- The INT (integer) of TIM (time) is the hour number.
- The FPT (fractional part) of TIM (time) is decimal hours; multiplied by 60 gives minutes, and the INT (integer) of that function gives the whole minutes.
- TIM multiplied by 60 gives minutes and decimal minutes.
- Taking FPT of TIM*60 (the decimal minutes) and multiplying it by 60 gives seconds and decimal seconds.
- The mask used for the hours is “#0” which suppresses leading zeros except the least significant one.
Converting string data to numeric data
Section titled “Converting string data to numeric data”There are a few commands used to convert string data to numeric data, depending on the resulting format desired. The most often used method involves the numeric function NUM. This provides the bridge to convert numbers in string data format into their base-10 equivalent numeric data. In case the string data contains anything other than numbers, an error branch is provided in the NUM Function to catch the problem before proceeding. For example:
**LET NUMBER_BUCKET = NUM(STRING_DATA$, ERR=**line-num)
This syntax executes the next sequential statement if no error existed or it goes to the line-number specified (without changing the numeric variable NUMBER_BUCKET) if there are any illegal characters in the string variable STRING_DATA$. Below are additional functions that can be used to convert string data to numeric data in a variety of formats:
- ASC (str [,ERR=line-num])
- returns the decimal ASCII value of the first character in a sting, str.
- CDN
- returns the current system date and time in SQL date format. January 1, 0001 returns a 1; the same day at noon returns 1.5; BC dates return negative values.
Converting numeric data to string data
Section titled “Converting numeric data to string data”This type of conversion offers a great deal of creativity in determining the look of the final string data result. Numeric data does not contain all the information necessary to relay its intent or purpose. For example, numeric data may represent dollars and cents, but the dollar sign is not a valid character in numeric data. The example shown earlier which represents the numeric function TIM, does so in a more readable format of hours, minutes, and seconds, using the concept of masking.
Masking
Section titled “Masking”Masking provides an automatic process by which data can be either edited or presented. The :verification option of the INPUT Directive is an example of using a mask to help verify or control data being taken from an outside source into a program. For complete information on this particular option refer to the description of the INPUT directive.
Using masking to present data is probably the most common method of converting numeric data into string data. The STR function is a good example of this method:
**LET ITEM_TO_BE_PRINTED$ = STR(**n:mask)
The mask must be a string expression. Valid characters within the mask are:
0 Zero specifies that a numeral in this position be printed, even if it is a zero. For example:
STR(0123456.7890:“00000000.000”) C> 00123456.789
# As the leading or trailing character in a mask, indicates that zeros in these positions should be replaced with a space. For example:
STR(0123456.7890:“#000000.000#”) C> 123456.789
STR(0123456.7890:“#00000.0#”) C> 123456.79
Note: Normally, a mask, which is too small to contain the number rounds the decimal portion but prints, the full integer size, unmasked.
-
Specifies that asterisks replace leading zeros in these positions. For example:
STR(0123456.7890:“****000000.0###”) C> ****123456.789
$ Indicates that leading zeros in these positions should be replaced with a space except the least significant zero, which should be replaced with a dollar sign. The first example shows a floating dollar sign and the second indicates a fixed-position dollar sign:
STR(0123456.7890:“$$$$$$$$0.000”) C> $123456.789
STR(0123456.7890:“$#######0.000”) C> $ 123456.789
, Indicates that a comma should be placed in this position if there are any significant digits to the left of this position. For example:
STR(0123456.7890:“###,###,##0.00##”) C> 123,456.789 STR(0123456.7890:“###,###,##0.000,”) C> 123,456.789,
. Indicates the relative position of the decimal point in the mask and the position where the decimal point is to be placed. For example:
STR(0123456.7890:“###,###,##0.000”) C> 123,456.789
STR(0123456.7890:“###,###,##0.”) C> 123,457. (rounded)
( ) Enclosing the mask in parentheses causes the resultant string to be enclosed in spaces if the numeric data is positive or unsigned and enclosed in parentheses if the numeric data is negative. If the number is negative, space characters between the ( (left parenthesis) and the - (minus sign) or first significant digit are removed. For example:
STR(0123456.7890:“(###,###,##0.000)”) C> 123,456.789 STR(-0123456.7890:“(###,###,##0.000)”) C> (123,456.789) STR(-0123456.7890:“(-###,###,##0.000)”) C>(-123,456.789)
Starting with Thoroughbred Basic 8.3.1, floating parentheses are available. For example:
STR(-12.34:“($###,###,##0.00)”) C> ($12.34)
+ Causes a plus sign to be placed in the position indicated if the number is positive and a minus sign if the number is negative. The plus sign may be floated up to the first significant number. For example:
STR(0123456.7890:“+###,###,##0.000”) C> +123,456.789 STR(0123456.7890:“###,###,##0.000+”) C> 123,456.789+
-
Causes a minus sign to be placed in the position indicated if the number is negative and a space if the number is positive. The minus sign may be floated up to the first significant number. For example:
STR(-0123456.7890:“-###,###,##0.000”) C> -123,456.789 STR(-0123456.7890:“###,###,##0.000-”) C> 123,456.789-
You can also use minus signs to separate groups of numbers, for example:
STR(-123456789:“000-00-0000”) C> 123-45-6789
- B
- Indicates that a blank is to be inserted into the resultant string at this position. Telephone numbers are good examples of this:
STR(8005551212:“000B000B0000”) C> 800 555 1212
For a slightly unusual approach, note the following combination of masking characters:
STR(-1*8005551212:“(000)B000-0000”) C> (800) 555-1212
- DR
- Indicates a debit. The characters CR are inserted in the resultant string if the numeric data is negative and DR is inserted if the numeric data is positive. For example:
STR(0123456.7890:“DR##,###,##0.000”)C> DR 123,456.789 STR(0123456.7890:“###,###,##0.000DR”) C> 123,456.789DR STR(-0123456.7890:“###,##0.000BDR”) C> 123,456.789 CR
- CR
- Indicates a credit. The characters CR are inserted in the resultant string if the numeric data is negative and two spaces are inserted if the numeric data is positive. For example:
STR(0123456.7890:“###,##0.000CR”) C> 123,456.789 STR(-0123456.7890:“###,##0.000CR”) C> 123,456.789CR
Any other character prints the character in the position indicated. For example:
STR(91234567890:“FSNB0NB000000B0000”) C> FSN 9N 123456 7890
Other characters used in masks
Section titled “Other characters used in masks”Since the mask is enclosed by “ “ (two double quotes), it cannot contain a double quote character. For masking, and for string data in general, there are special characters, which can be used to facilitate building string data.
- QUO This is the double quote character (
- $22$ in ASCII) and should be used to insert a double quote in a string. For example:
PRINT “ABC” yields ABC
PRINT QUO + “ABC” + QUO yields “ABC”.
- SEP
- This is the field separator character that is used in data record formats to separate one field from another. It is normally a $8A$ character, but may vary for certain operating system environments. Use of the SEP instead of a hexadecimal constant ($8A$) allows programs to be insensitive to such operating system changes.
- ESC
- This is the escape character for the system, and is normally a $1B$ value. For example:
LET A1$ = ESC + “6” + BIN(31,1)
This places the hexadecimal value $1B361F$ in A1$, which is the sequence of codes to change the color configuration on a monitor to color 31 (high intensity white characters on blue background). This, too, may vary from one operating system environment to another. Use of ESC helps avoid system dependency.
When data is too large for the mask
Section titled “When data is too large for the mask”If the numeric data is too large for the mask specified, an attempt is made to salvage the numeric data. The integer portion of the numeric data is printed with no masking. The decimal portion of the numeric data is rounded, if necessary, to the number of decimal positions in the mask. For example:
STR(0123456.7890:“#,##0.0#”) C> 123456.79
The decimal portion is rounded to the number of places in the mask, so .7890 becomes .79 in this case.
From the Thoroughbred Basic Developer Guide, version 8.9.1. Open this page in the PDF