Previous | Contents | Index |
BASIC provides the following matrix functions:
TRN
INV
DET
With these functions, you can transpose and invert matrices and find
the determinant of an inverted matrix.
7.7.2.1 TRN Function
The TRN function transposes a matrix. When you transpose a matrix, BASIC interchanges the array's dimensions. For example, a matrix with n rows and m columns is transposed to a matrix with m rows and n columns. The elements in the first row of the input matrix become the elements in the first column of the output matrix. You cannot transpose a matrix to itself; MAT A = TRN(A) is invalid.
The following example creates a 3-by-5 matrix, transposes it, and prints the results:
DIM B(3,5) MAT READ B MAT A = TRN(B) DATA 1,2,3,4,5 DATA 6,7,8,9,10 DATA 11,12,13,14,15 MAT PRINT B; MAT PRINT A; END |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 6 11 2 7 12 3 8 13 4 9 14 5 10 15 |
The INV function inverts a matrix. BASIC can invert a matrix only if its subscripts are identical and it can be reduced to the identity matrix by elementary row operations. The input matrix multiplied by the output matrix (its inverse) always gives the identity matrix as a result.
MAT INPUT first_array(3,3) MAT PRINT first_array; PRINT MAT inv_array = INV (first_array) MAT PRINT inv_array; PRINT MAT mult_array = first_array * inv_array MAT PRINT mult_array; PRINT D = DET PRINT D |
? 4,0,0,0,0,2,0,8,0 4 0 0 0 0 2 0 8 0 .25 0 0 0 0 .125 0 .5 0 1 0 0 0 1 0 0 0 1 -64 |
The DET function returns the determinant of a matrix. The DET function returns a floating-point number that is the determinant of the last matrix inverted. If you use the DET function before inverting a matrix, the value of DET is zero.
This chapter briefly describes how to define program objects,
explicitly assign data types, and allocate and use data storage.
8.1 Declarative Statements
You use declarative statements to define objects in a BASIC program. Objects can be variables, arrays, constants, and user-defined functions within a program module. They can also be routines, variables, and constants external to the program module. Declarative statements always assign names to the objects declared and usually assign other attributes, such as a data type, to them. Declarative statements can also be used to define user-defined data types (RECORD statements). See Chapter 9 for more information about the RECORD statement.
You use declarative statements to assign data types to:
By declaring the objects used in your program, you make the program
easier to understand, modify, and debug.
8.2 Data Types
At its most fundamental level, a data type is a format for information storage. All information is stored in the computer as bit patterns (groups of ones and zeros). Data types specify how the computer should interpret these patterns.
BASIC programs allow five general data types: integer, floating-point, string, packed decimal, and record. Each data type is suited for a particular type of task. For example, integers are useful for numeric computations involving whole numbers, strings provide a way to manipulate alphanumeric characters, and packed decimal data is useful for manipulating numeric values that require precise representation.
For more information about Alpha BASIC and VAX BASIC data types,
see the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual.
8.3 Setting the Default Data Type and Size
There are two ways to set the default data type and size for your program:
The OPTION statement can override the defaults set with qualifiers. For example, the following statement sets the default integer type to be LONG:
OPTION SIZE = INTEGER LONG |
You can have more than one OPTION statement in a program module; however, OPTION statements can be preceded only by a SUB, FUNCTION, REM, or another OPTION statement.
Note that the OPTION statement can also specify the following:
See the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual for more information about the OPTION statement.
The OPTION statement in the following example specifies that all program variables must be explicitly typed and that all implicitly typed constants are INTEGER. In addition, any variable typed as INTEGER is a LONG integer and any variable typed as REAL is a DOUBLE floating-point number.
OPTION TYPE = EXPLICIT, ! Variables must be declared & CONSTANT TYPE = INTEGER, ! All implicit constants be integers & SIZE = INTEGER LONG, ! 32-bit integers by default & SIZE = REAL DOUBLE ! 64-bit floating-point ! numbers by default |
You can create variables of other data types by explicitly declaring
them with the DECLARE, COMMON, or MAP statement.
8.4 Declaring Variables
A variable is a named quantity whose value can change during program execution. Variables may be implicitly or explicitly declared. BASIC accepts the following types of variables:
For more information about declaring variables, see the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual.
8.5 Declaring Named Constants
A constant is a value that does not change during program execution. You can declare named constants within a program unit with the DECLARE statement. You can also refer to constants outside the program unit with the EXTERNAL statement. In addition, BASIC provides notation for binary, octal, decimal, and hexadecimal constants.
For more information about named constants, see the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual.
8.6 Operations with Multiple Data Types
When an expression contains operands of different data types, it is called a mixed-mode expression. Before a mixed-mode expression can be evaluated, the operands must be converted, or promoted, to a common data type. The result of the evaluation can also be converted depending on the data type of the variable to which it is assigned.
When assigning values to variables, BASIC converts the result of the expression to the data type of the variable. If the value of the expression is outside the allowable range of the variable's data type, BASIC signals "Integer error or overflow," "Floating-point error or overflow," or "DECIMAL error or overflow."
In general, BASIC promotes operands with different data types
to the lowest data type that can hold the largest and most precise
possible value of either operand's data type. BASIC then
performs the operation in that data type, and yields a result of that
data type. If the result of the expression is assigned to a variable,
BASIC converts the result to the data type of the variable. For
more information about multiple data types, see the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual.
8.7 Allocating Dynamic and Static Storage
BASIC programs allocate both dynamic and static storage. Dynamic storage is allocated when the program executes, whereas the size of static storage does not change during program execution.
Variables and arrays declared by the following means use dynamic storage:
Normally, string variables and arrays declared in these ways are dynamic strings, and their length can change during program execution. However, if you declare or dimension an array of a user-defined data type (a RECORD name), then all string variables and arrays are fixed-length strings. See Chapter 9 for more information about the RECORD statement.
Variables and arrays appearing in MAP or COMMON statements use static storage. Hence all string variables appearing in MAP or COMMON statements are fixed-length strings. MAP and COMMON statements create a named storage area called a program section, or PSECT. MAP statements require a map name, but in COMMON statements the name is optional. The PSECT name is the same as the map or common name. If you do not specify a common name, BASIC supplies a default PSECT name of $BLANK.
The remainder of this section explains how to use COMMON and MAP
statements for static storage.
8.7.1 COMMON Statement
The COMMON statement defines a named area of storage (called a PSECT). Any BASIC subprogram can access the values in a common area by specifying a common with the same name. An item in a COMMON statement can be any one of the following:
The amount of storage reserved for a variable depends on its data type. You can specify a length for string variables and string array elements that appear in a COMMON statement. If you do not specify a length, the default is 16. The following statement specifies 2 bytes for emp.code, 3 bytes for wage.code, and 22 bytes for dep.code:
COMMON (code) STRING emp.code=2, wage.code=3, dep.code=22 |
In a single program module, multiple common areas with the same name allocate storage end-to-end in a single PSECT. That is, BASIC concatenates all common areas with the same name in the same program module, in order of appearance. For example, the following statements allocate storage for five LONG integers in a single PSECT named into:
COMMON (into) LONG call_count, sub1_count, sub2_count COMMON (into) LONG sub3_count, sub4_count |
When you explicitly declare an array, BASIC allows you to specify both upper and lower bound values. The value you supply as the upper bound determines the maximum subscript value for a given dimension, and the value you supply for the lower bound determines the minimum subscript value for a given dimension.
For more information about specifying bounds with the COMMON statement,
see Chapter 7 and the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual.
8.7.2 MAP Statement
The MAP statement, like the COMMON statement, creates a named area of static storage. However, if a program module contains multiple maps with the same name, the maps are overlaid on the same area of storage, rather than being concatenated.
When used with the MAP clause of the OPEN statement, the storage allocated by the MAP statement becomes the record buffer for that file. Variables in the MAP statement correspond to fields in the file's records.
A map item can be one of the following:
When you explicitly declare an array, BASIC allows you to specify both upper and lower bound values. The value you supply as the upper bound determines the maximum subscript value for a given dimension, and the value you supply for the lower bound determines the minimum subscript value for a given dimension.
For more information about specifying bounds with the MAP statement,
see Chapter 7 and the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual.
8.7.2.1 Single Maps
You associate a map with a record buffer by referencing the map in the OPEN statement.
The MAP statement must appear before any reference to map variables. Changes to map variables do not change the actual records in the file. To transfer the changed variables to the file, you must use the PUT or UPDATE statement. For more information, see Chapter 14.
The following program example uses map variables to access fields in payroll records:
WHEN ERROR USE eof_handler DECLARE INTEGER CONSTANT EOF = 11 MAP (PAYROL) STRING emp_name, LONG wage_class, & STRING sal_rev_date, SINGLE tax_ytd OPEN "payroll.dat" FOR INPUT AS FILE #4% & ,ORGANIZATION SEQUENTIAL & ,ACCESS READ & ,MAP PAYROL OPEN "payrol.new" FOR OUTPUT AS FILE #5% & ,ORGANIZATION SEQUENTIAL & ,ACCESS WRITE & ,MAP payrol PRINT "PAYROLL VERIFICATION" get_loop: WHILE 1% = 1% GET #4 PRINT emp_name, wage_class, sal_rev_date, tax_ytd PRINT "YOU CAN CHANGE:" PRINT "1. EMPLOYEE NAME" PRINT "2. WAGE CLASS" PRINT "3. REVIEW DATE" PRINT "4. TAX YEAR-TO-DATE" PRINT "5. DONE" read_loop: WHILE 1% = 1% INPUT "CHANGES? ANSWER WITH YES OR NO" ; chng$ IF chng$ = "NO" THEN ITERATE get_loop ELSE INPUT "NUMBER" ;number% END IF SELECT number% CASE 1 INPUT "EMPLOYEE NAME"; emp_name CASE 2 INPUT "WAGE CLASS"; wage_class CASE 3 INPUT "REVIEW DATE";sal_rev_date CASE 4 INPUT "TAX YEAR-TO-DATE"; tax_ytd CASE 5 EXIT read_loop CASE ELSE PRINT "Invalid response -- please try again" END SELECT NEXT PUT #5 NEXT END WHEN HANDLER eof_handler IF ERR = EOF THEN PRINT "End of file" ELSE EXIT HANDLER END IF END HANDLER END |
When a program contains more than one map with the same name, the storage allocated by these MAP statements is overlaid. This technique is useful for manipulating strings. Figure 8-1 shows multiple maps and maps in use.
Figure 8-1 Multiple Maps
When you use more than one map to access a record buffer, BASIC uses the size of the largest map to determine the size of the record. (The RECORDSIZE clause of the OPEN statement can override this map-defined record size. For more information, see Chapter 14.)
You can also use multiple maps to interpret numeric data in more than one way. The following example creates a map area named barray. The first MAP statement allocates 26 bytes of storage in the form of an integer BYTE array. The second MAP statement defines this same storage as a 26-byte string named ABC. When the FOR...NEXT loop executes, it assigns values corresponding to the ASCII values for the uppercase letters A to Z.
MAP (barray) BYTE alphabet(25) MAP (barray) STRING ABC = 26 FOR I% = 0% TO 25% alphabet(I%) = I% + 65% NEXT I% PRINT ABC END |
ABCDEFGHIJKLMNOPQRSTUVWXYZ |
FILL items reserve space in map and common blocks and in record buffers accessed by MOVE or REMAP statements. Thus, FILL items mask parts of the record buffer and let you skip over fields and reserve space in or between data elements.
FILL formats are available for all data types. Table 8-1 summarizes the FILL formats and their default allocations if no data type is specified.
FILL Format | Representation | Bytes Used |
---|---|---|
FILL | Floating-point | 4, 8, 16, or 32 |
FILL( n) | n floating-point elements | 4 n, 8 n, 16 n, or 32 n |
FILL% | Integer (BYTE, WORD, LONG, or QUAD) | 1, 2, 4, or 8 |
FILL%( n) | n integer elements | 1 n, 2 n, 4 n, or 8 n |
FILL$ | String | 16 |
FILL$( n) | n string elements | 16 n |
FILL$ = m | String | m |
FILL$( n) = m | n string elements, m bytes each | m * n |
In the applicable formats of FILL, n represents a repeat count, not an array subscript. FILL(n), for example, represents n real elements, not n+1. |
You can also use data-type keywords with FILL and optional data type- suffixes. The data-type and storage requirements are those of the last data type specified. For example:
MAP (QED) STRING A, FILL$=24, LONG SSN, FILL%, REAL SAL, FILL(5) |
This MAP statement uses data-type keywords to reserve space for:
You can specify user-defined data types (RECORD names) for FILL items. In the following example, the first line defines a RECORD of data type X. The MAP statement contains a fill item of this data type, thus reserving space in the buffer for one RECORD of type X.
RECORD X REAL Y1, Y2(10) END RECORD X MAP (QED) X FILL |
See Chapter 9 for more information about the RECORD statement.
8.7.4 Using COMMON and MAP Statements in Subprograms
The COMMON and MAP statements create a block of storage called a PSECT. This common or map storage block is accessible to any subprogram. A BASIC main program and subprogram can share such an area by referencing the same common or map name.
The following example contains common blocks that define:
!In a main program COMMON (A1) STRING A, B = 10, LONG C . . . !In a subprogram COMMON (A1) STRING X, Z = 10, LONG Y |
If a subprogram defines a common or map area with the same name as a common or map area in the main program, it overlays the common or map defined in the main program.
Multiple COMMON statements with the same name behave differently depending on whether these statements are in the same program module. If they are in the same program module, then the storage for each common area is concatenated. However, if they are in different program units, then the common areas overlay the same storage. The following COMMON statements are in the same program module; therefore, they are concatenated in a single PSECT. The PSECT contains two 32-byte strings.
COMMON (XYZ) STRING A = 32 COMMON (XYZ) STRING B = 32 |
In contrast, the following COMMON statements are in different program modules, and thus overlay the same storage. Therefore, the PSECT contains one 32-byte string, called A in the main program and B in the subprogram.
!In the main program COMMON (XYZ) STRING A = 32 . . . !In the subprogram COMMON (XYZ) STRING B = 32 |
Although you can redefine the storage in a common section when you access it from a subprogram, you should generally not do so. Common areas should contain exactly the same variables in all program modules. To make sure of this, you should use the %INCLUDE directive, as shown in the following example:
COMMON (SHARE) WORD emp_num, & DECIMAL (8,0) salary, & STRING wage_class = 2 . . . !In the main program %INCLUDE "COMMON.BAS" . . . !In the subprogram %INCLUDE "COMMON.BAS" |
If you use the %INCLUDE directive, you can lessen the risk of a typographical error. For more information about using the %INCLUDE directive, see Chapter 17.
If you must redefine the variables in a PSECT, you should use the MAP statement or a record with variants for each overlay. When you use the MAP statement, use the %INCLUDE directive to create identical maps before redefining them, as shown in the following example. The map defined in MAP.BAS is included in both program modules as a 40-byte string. This map is redefined in the subprogram, allowing the subprogram to access parts of this string.
MAP (REDEF) STRING full_name = 40 . . . !In the main program %INCLUDE "MAP.BAS" . . . !In the subprogram %INCLUDE "MAP.BAS" MAP (REDEF) STRING first_name=15, MI=1, last_name=24 |
Previous | Next | Contents | Index |