Using variables and values in computation: Difference between revisions
mNo edit summary |
mNo edit summary |
||
Line 356: | Line 356: | ||
<p class="code">NO FIELD SAVE | <p class="code">NO FIELD SAVE | ||
</p> | </p> | ||
<p>If you do not intend to use any of the STRING array elements as field name variables, you should select the NO FIELD SAVE option, to save space in the user work areas described in [[Large | <p>If you do not intend to use any of the STRING array elements as field name variables, you should select the NO FIELD SAVE option, to save space in the user work areas described in [[Large request considerations#STBL (character string table)|STBL (character string table)]]. (Field name variables are discussed in detail on [[#Field name variables|Field name variables]].)</p> | ||
<p>An element of a STRING array can be used as a field name variable even if NO FIELD SAVE is specified. However, when the value of the element is referred to as a field name, extra processing and additional disk I/O are required for each reference after the first.</p> | <p>An element of a STRING array can be used as a field name variable even if NO FIELD SAVE is specified. However, when the value of the element is referred to as a field name, extra processing and additional disk I/O are required for each reference after the first.</p> | ||
===Assigning values to %variables=== | ===Assigning values to %variables=== | ||
Line 1,051: | Line 1,051: | ||
<p class="note"><b>Caution:</b> Some caution is required when substituting %variables for NOTE statement values. The NOTE statement retains up to 255 characters, while an undeclared %variable retains only the default length set by the VLEN parameter. If a %variable is used for a long field value, the length parameter for the %variable must be reset to avoid truncation.</p> | <p class="note"><b>Caution:</b> Some caution is required when substituting %variables for NOTE statement values. The NOTE statement retains up to 255 characters, while an undeclared %variable retains only the default length set by the VLEN parameter. If a %variable is used for a long field value, the length parameter for the %variable must be reset to avoid truncation.</p> | ||
====Impact on STBL space==== | ====Impact on STBL space==== | ||
<p>Another difference between %variables and NOTE statement values is the use of space in the system work area STBL. For more information on STBL, refer to [[Large | <p>Another difference between %variables and NOTE statement values is the use of space in the system work area STBL. For more information on STBL, refer to [[Large request considerations#STBL (character string table)|STBL (character string table)]]."</p> | ||
===Field name variables=== | ===Field name variables=== | ||
<p>Field name variables permit indirect reference to field names, thereby permitting many procedures and requests to be generalized without using dummy strings (refer to [[Procedures#Dummy strings in procedures|Dummy strings in procedures]] for a discussion). The actual field names used in a particular procedure or request are specified when the request is executed. Field name variables are extensions of the %variables described in the preceding section. </p> | <p>Field name variables permit indirect reference to field names, thereby permitting many procedures and requests to be generalized without using dummy strings (refer to [[Procedures#Dummy strings in procedures|Dummy strings in procedures]] for a discussion). The actual field names used in a particular procedure or request are specified when the request is executed. Field name variables are extensions of the %variables described in the preceding section. </p> |
Revision as of 17:56, 2 January 2014
Overview
User Language lets you use variables to represent values. You can use a User Language variable, called percent variable (%variable), because variable names must start with a percent sign, any place in a User Language statement that requires a value.
You can declare %variables for a single value or as an array. For the purposes of discussing User Language, the term %variable is used to mean both a %variable and an element of a %variable array. The features discussed in this chapter enable you to generate additional information based on data in the file.
Special types of variables
In addition to the basic %variables (and variable arrays) discussed in this chapter, User Language provides the following types of variables:
Type of variable | See... |
---|---|
Field name | Field name variables |
Screen variables | Full-screen variables |
Image variables | Defining image items and the sections that follow describing types of images |
%Variables as parameters | Flow of Control in User Language |
Values
You can specify User Language values by using:
- Literals (quoted strings)
- Numeric constants
- Field values (values derived from field retrievals)
- %Variables
User Language performs value conversions on values, as described in this chapter.
Arithmetic operations
Using values and/or %variables, you can construct expressions to perform arithmetic operations, which are discussed in this chapter.
Default variable attributes
Model 204 parameters that set default attributes for variables
Model 204 parameters that set default attributes for variables lists three Model 204 parameters that establish the default type, length, and number of decimal places for all types of User Language variables:
Parameter | Meaning | Default |
---|---|---|
VTYPE | Type: FIXED, FLOAT, STRING, or UNDEFINED | STRING |
VLEN | Length of STRING variables | 20 |
VDP | Number of decimal places in FIXED or STRING variables | 0 |
You can change the defaults established by these parameters as follows:
- The values of VTYPE, VLEN, and/or VDP can be changed by any user for the duration of the terminal session with the RESET command.
- The value of any of these parameters can be overridden for the duration of a request with the VARIABLES ARE statement.
- The variable type, length, and/or number of decimal places for any given variable can be explicitly specified in the declaration statement for that variable. This has the effect of overriding the respective values established by VTYPE, VLEN, and VDP, as well as the values established by the VARIABLES ARE statement.
VTYPE, VLEN, and VDP are discussed where relevant elsewhere in this chapter. Also, refer to the Rocket Model 204 Parameter and Command Reference Manual for more on user parameters.
Relationship between default values and variable declarations
A variable can be declared:
- Explicitly, in a declaration statement (see DECLARE statements for %variables)
- Implicitly, in an assignment statement (see Assignment statements). When a variable is declared implicitly, it takes on the attributes established by the VTYPE, VLEN, and VDP parameters (as modified by any VARIABLES ARE statement that may precede the assignment statement).
VARIABLES ARE statement
The VARIABLES ARE statement overrides, for the remainder of the current request, the default variable type, length, and/or number of decimal places established by the VTYPE, VLEN, and/or VDP parameters, or by an earlier VARIABLES ARE statement. It is particularly useful if you don't want to rely on VTYPE, VLEN, and VDP, and when most of the %variables used in a request are of the same type and length.
A VARIABLES ARE declaration has no effect on variables which have been declared (either implicitly or explicitly) earlier in the request. The defaults established by a VARIABLES ARE statement remain in effect until the next VARIABLES ARE declaration or until the end of the request, whichever comes first.
Syntax
The format of the VARIABLES ARE statement is:
VARIABLES ARE {FIXED [DP n] | FLOAT | STRING [LEN n] [DP {n | *}] | UNDEFINED}
VARIABLES ARE UNDEFINED statement
The VARIABLES ARE UNDEFINED statement forces you to explicitly declare all variables. If this statement is used in a request and Model 204 encounters an undeclared variable, an error message is issued.
The VARIABLES ARE UNDEFINED statement sets both the default LEN and DP options to 0. Therefore, when VARIABLES ARE UNDEFINED is in effect, %variables declared as STRING must have the LEN specified or an error message is issued.
Declaring %variables and %variable arrays
You can declare a variable and subsequently assign and reset that variable any number of times during a User Language request. You can use a variable declaration statement to specify:
- Type of variable
- Length of the variable and number of decimal places
- Number of elements if the variable is an array
- Use of the optional field save feature
Variable arrays
Variables also can be declared to be arrays of up to three dimensions. An element of a %variable array is equivalent to a %variable that is not part of an array. It can be used anywhere that a %variable can be used.
DECLARE statements for %variables
To temporarily set or reset the default variable type, length, and number of decimal places for a particular %variable or %variable array in a request, use the DECLARE statement.
Syntax
In the following syntax diagrams, the first declaration statement is for numeric %variables and the second declaration statement is for string %variables
- Syntax for numeric %variables:
- Syntax for string %variables:
[DECLARE] %variable [IS] {FIXED [DP n] | FLOAT} [ARRAY(d1 [,d2 [,d3]])] [INITIAL(numeric-expression)] [STATIC] [COMMON]
[DECLARE] %variable [IS] STRING [LEN n] [DP [n |*}] [ARRAY(d1 [,d2 [,d3]])] [NO FIELD SAVE] [INITIAL('EBCDIC-string' | expression)] [STATIC] [COMMON]
Where
- The keyword DECLARE is optional.
- INITIAL attribute assigns an initial value to a %variable at compilation time, without using any excess QTBL, STBL, or VTBL space and CPU usage. The INITIAL attribute is permitted only for numeric expressions or EBCDIC string variables, and not for arrays of any type or DBCS variables.
- STATIC attribute limits assignment to a %variable to the INITIAL attribute and requires the INITIAL attribute to set the %variable's initial (and only) value.
- The various other components of this statement, except for COMMON, are described later in this chapter; COMMON is discussed in Common elements.
If you want to use the COMMON attribute on a %variable declaration with the INITIAL and STATIC attributes, the COMMON attribute must be the last token in the statement. For example:
%X FLOAT INITIAL (3) STATIC COMMON
Usage %Variable INITIAL value assignment
An INITIAL value longer than the maximum length results in a compilation warning message:
M204.2493: VARIABLE TOO SMALL FOR INITIAL VALUE
Examples
The following examples use the STATIC or INITIAL attribute.
- In the first example, set %X to the value ABC, using the STATIC attribute. The value cannot be changed during request evaluation:
- The next example uses a %variable that can be changed during request evaluation:
- The following compiler error message is displayed if you attempt to assign a value to a %variable that has been declared STATIC:
- This next example illustrates using the STATIC attribute and an expression with the INITIAL attribute.
%X IS STRING LEN 3 INITIAL('ABC') STATIC
%Y IS STRING LEN 3 INITIAL('ABC')
*** M204.0542: EDIT COMPLETE - GO *** 1 M204.2490: ILLEGAL ASSIGNMENT TO STATIC %VARIABLE %X=5 (FILE=CCATEMP, PROCEDURE=0, LINE=3) ==5 *** 2 M204.0228: PART OF STATEMENT IGNORED *** M204.1042: COMPILATION ERRORS
BEGIN %X IS STRING LEN 3 INITIAL('ABC') STATIC %Y IS STRING LEN 3 INITIAL('DEF') STATIC %ALPHA IS STRING LEN 6 - INITIAL($SUBSTR(%X,2,1) WITH $SUBSTR(%Y,2,1)) STATIC PRINT %ALPHA END ***M204.0542:EDIT COMPLETE - GO BE >
%Variable names
A variable name can consist of any number of letters, numbers, and some special characters (for example, period or underscore). The first character of the name must be a percent sign (%). The name can have no embedded blanks, colons, or any of the following Model 204-reserved characters:
= | + | $ |
( | * | ¬ (not sign) |
) | ' | - (minus sign/hyphen) |
; | < | / |
, | > | : |
The following guidelines apply to certain special characters that are allowed in %variable names:
- The @ and # characters also are reserved, unless they are reset by the user through the FLUSH and ERASE parameters.
- Dummy string characters (??, ?$, ?&) can be used in variable names, but they perform dummy string substitution, as described in Using ?$ and ?& dummy strings.
Note: The ¬
reserved character is the EBCDIC "not sign," which has the hexadecimal value 5f
.
Relationship to VARIABLES ARE statement
The type, length, and decimal place settings established for a particular %variable by a DECLARE %variable statement are not overridden by a VARIABLES ARE statement. For example, if the statement:
DECLARE %NAME STRING LEN 30
is followed by the statement:
VARIABLES ARE FIXED
then %NAME remains a string of length 30.
%Variable types
A %variable can be declared as one of three distinct types:
- FIXED (fixed-point numeric)
- FLOAT (floating-point numeric)
- STRING (alphanumeric string)
Using FIXED or FLOAT for arithmetic statements
Defining %variables as FIXED or FLOAT improves the performance of arithmetic statements. If the result of an arithmetic operation is being assigned to a %variable, the result is not converted before assignment if the arithmetic operands are of the same type.
Arithmetic operations are performed most efficiently if all %variables are defined with matching options: either as FLOAT or as FIXED, and with no decimal places or the same number of decimal places. To operate Model 204 as efficiently as possible, avoid mixed-type arithmetic. Use STRING variables only when string manipulations are required.
An arithmetic operation where both operands are FIXED requires rules to determine the scale (number of decimal places) of the result. See FIXED precision arithmetic for detailed information on the way Model 204 handles FIXED arithmetic operations.
Arithmetic result types
Arithmetic result types shows the types and the results for various combinations of operands in an arithmetic statement. The result described in the table refers to the result of an arithmetic operation, which might be an intermediate result. If the final result is being assigned to a %variable of a different type, it is converted to match.
Operand 1 | Operand 2 | Arithmetic result type |
---|---|---|
FLOAT | FLOAT | FLOAT |
FLOAT | FIXED | FLOAT |
STRING | FLOAT | FLOAT |
STRING | STRING | FLOAT |
STRING | FIXED | FIXED |
FIXED | FIXED | FIXED |
%Variable lengths
FIXED %variables
%Variables declared as FIXED can have a decimal place specification associated with them. For example:
DECLARE %TOTAL FIXED DP 2
represents a dollar total. A FIXED %variable can contain as many as 15 significant digits, including decimal places. There can be as many as nine decimal places.
FLOAT %variables
Variables declared as FLOAT are stored as double-precision floating-point numbers. Precision is guaranteed to 15 decimal digits; the exponent must be between 75 and -74.
Note: The rounding algorithm for floating point numbers was improved with Version 2.2 to provide more accurate results. In a few cases this might cause inconsistencies with the results from Model 204 releases prior to Version 2.2, particularly for numbers with very large exponents (for example, -50, +55, and so on) and for numbers just under powers of 10.
Running the following example under Version 2.2 or greater and under an earlier release would illustrate these potential differences (%x is a FLOAT variable):
%X IS FLOAT %X = 0.999999999999997E-73 FOR %I FROM 1 TO 147 PRINT %X %X = %X*10 END FOR
STRING %variables
Variables declared as STRING can have a maximum length as well as an optional decimal place specification associated with them. For example:
DECLARE %NAME STRING LEN 20 DP 2 VARIABLES ARE STRING LEN 7
The first statement (above) declares the %NAME variable as STRING, with a maximum length of 20 and two decimal places. The second statement sets the defaults for %variables not explicitly declared: STRING with a maximum length of 7 and no decimal places.
Additionally, the decimal place for STRING %variables can be variable by specifying DP *. This causes all decimal digits to be placed in the string. For example:
BEGIN %AMOUNT IS STRING LEN 10 DP * %AMOUNT = 1.2 PRINT %AMOUNT %AMOUNT = 1.23 PRINT %AMOUNT %AMOUNT = 1.234 PRINT %AMOUNT END
Yields:
1.2 1.23 1.234
The maximum length of a STRING variable is 255 characters. Decimal places, and the decimal point itself, are included in the specified length. Alternatively, the default values for length and decimal places can be used. An attempt to store a value longer than the declared or default length results in truncation.
The current length of a STRING variable is determined by the value put into the STRING variable. You can use the $LEN function to find the current length of a STRING variable (see $LEN).
If the VARIABLES ARE UNDEFINED statement is used, the values for length and decimal places must be specified with each STRING %variable declaration.
%Variable arrays
You can define %variables as arrays of one, two, or three dimensions with the DECLARE %variable statement. For example:
DECLARE %CODES STRING LEN 5 ARRAY(100)
defines a one-dimensional array of up to 100 message codes, each five characters in length.
DECLARE %TRANSACTION FIXED DP 2 ARRAY(12,10000)
defines a two-dimensional array of dollar transactions for a store. The array contains up to 10,000 transactions for each of 12 departments.
DECLARE %READINGS FLOAT ARRAY(3,10,80)
defines a three-dimensional array consisting of up to 80 atmospheric readings of three distinct types from 10 monitoring stations.
Array elements must be of one type
All elements of an array must have the same type (FIXED, FLOAT, or STRING) and element length.
%Variable array references
An array can be referred to only after it has been declared in an array can have as many as three declared dimensions. A subscript value must be supplied for each dimension.
If a variable is declared as an array, it must always be referenced with subscripts.
Each of the subscript values that refers to a dimension can be a number or an expression. For example:
%CODE(2) %READING(3,200-%A/%B,%N)
As shown in the examples, the expression can contain references to other %variables. The subscript value is converted to an integer. Any fraction is truncated before the subscript value is used as the array subscript. The subscript value must fall within the declared range of dimensions.
NO FIELD SAVE option
When a STRING %variable array is declared, you can specify:
NO FIELD SAVE
If you do not intend to use any of the STRING array elements as field name variables, you should select the NO FIELD SAVE option, to save space in the user work areas described in STBL (character string table). (Field name variables are discussed in detail on Field name variables.)
An element of a STRING array can be used as a field name variable even if NO FIELD SAVE is specified. However, when the value of the element is referred to as a field name, extra processing and additional disk I/O are required for each reference after the first.
Assigning values to %variables
Assignment statements
Syntax
The format of the statement used to calculate and assign the value of %variables is:
%variablename = expression
The name of the %variable to be set appears to the left of the equal sign and the expression to whose value the %variable is to be set is at the right. (See also Expressions.)
For Large Object data, a compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.
M204.2691: BUFFER ASSIGNMENT MUST REFERENCE LARGE OBJECT FIELD
and/or
M204.2704: BUFFER REFERENCE REQUIRES LOB FIELD
Example
These statements are valid assignments:
%AGENT = AGENT %NAME = 'DALE STERN' %RESULT = (%INCREASE + TOTAL PREMIUM) * .01
Note that %AGENT is legal as a variable name even if AGENT is a field name in the file. The variable and the field are not related to each other.
Relationship between %variable assignment and declaration
Normally, an assignment statement precedes a %variable reference in another statement. If a %variable is going to be declared with the DECLARE %variable statement, the declaration must precede the first use of the %variable. If an assignment statement does not precede the %variable reference, or the variable has not been declared, then default values (null values for STRING types, 0 for FIXED and FLOAT) are assigned to the %variable.
Truncation vs. rounding on assignment
It is possible, in an assignment statement, for the length of the assigned value to exceed the maximum length for that %variable (as determined in the variable declaration statement, the VARIABLES ARE statement, or the value of the VLEN or VDP parameter). The way Model 204 treats this situation depends on the %variable type.
- For FLOAT %variables, the assigned value is rounded to 15 significant digits.
- For FIXED %variables, if the number of places to the left of the decimal point in the assigned value, plus the number of decimal places declared (not assigned) exceeds 15, Model 204 returns an error message and assigns a value of zero. Otherwise, if the number of decimal places assigned exceeds the number declared, Model 204 truncates the assigned value to the number of decimal places declared. For example, the following request:
- For STRING %variables, if the number of characters in the assigned value exceeds the maximum declared length (or, if not declared, the default length set by the VLEN parameter), the assigned value is truncated to the maximum length allowed.
BEGIN %X IS FIXED DP 0 %Y IS FLOAT %Z IS FLOAT %X = 1.9 %Y = 5 %Z = %X * %Y PRINT '%X = ' WITH %X PRINT '%Y = ' WITH %Y PRINT '%X * %Y = ' WITH %Z END
results in this output:
%X = 1 %Y = 5 %X * %Y = 5
The value of %X is truncated from 1.9 to 1 upon assignment for both display and computation.
Changing %variable values
You can change the value of a %variable at any point in a request by using an assignment statement. The variable is stored for the duration of the request that assigns it, including any continuations, and is then deleted.
At the beginning of a request, all %variables are set equal to a null string, or to zero, depending on their types.
During a request, a %variable can be set equal to another %variable, a quoted string, a number, a field value, a noted value, a function, a count of records or field occurrences, an occurrence number, a null value, or the result of a computation.
Understanding INITIAL processing
Code written using an INITIAL assignment for both %variables results in the assigned value of %X as the INITIAL value assigned for %Y as both assignments are resolved at compilation. For example:
BEGIN %X IS STRING INITIAL(1) /? %X assigned the INITIAL value of 1, at compilation ?/ %Y IS FIXED INITIAL(%X) /? %Y assigned the INITIAL value of %X, at compilation ?/ PRINT 'Y = ' %Y END Y = 1
An INITIAL value assignment in the format, %Y IS FIXED INITIAL (%X), will not resolve to the value of %X, if %X was assigned in the format %X = 1. %X = 1 format variable assignments are resolved at evaluation, subsequent to compilation. INITIAL value assignments are resolved at compilation.
The following code reflects this processing:
BEGIN %X = 1 /? %X assigned the value of 1 at evaluation ?/ %Y IS FIXED INITIAL(%X) /? %Y assigned the INITIAL value at compilation ?/ PRINT 'Y = ' %Y END Y = 0
The %X value is assigned at evaluation. The INITIAL value is assigned at compilation, prior to the evaluation of %X = 1. The result is that %Y is assigned the default value, zero (0), for its type of FIXED.
Expressions
Expressions are evaluated by Model 204 and used to assign values to %variables and function arguments, or included as operands in computation or conditional statements.
Syntax
An expression has this format:
{operand | (expression)} [operator {operand | (expression)}]...
Where
operand is one of the following:
- %%variable (field name variable)
- %variable or element of %variable array
- COUNT IN label
- Field name
- Function
- Number
- OCCURRENCE IN label
- Quoted string
- VALUE IN label
and operator can be arithmetic, Boolean, comparison, or concatenation.
Operator order of precedence
Operator order of precedence lists the operators used within expressions in order of precedence. Parentheses can be used to override the order.
Order of precedence | Operator |
---|---|
First | IS PRESENT, IS NOT PRESENT |
Second | - (unary minus) |
Third | *,/ |
Fourth | +,- |
Fifth | WITH |
Sixth | EQ, =, LE, <=, GT, >, GE, >=, NE, ¬=, LT, IS [NOT] LIKE |
Seventh | NOT |
Eighth | AND |
Ninth | OR |
Tenth | AND (implied by a new line; occurs only in an IF statement) |
Notes:
- The first character (
¬
) of the inequality test above is the EBCDIC "not sign", which has the hexadecimal value5f
.- For a description of the
IS [NOT] LIKE
clauses, see the syntax of Is Like patterns.
Incomplete expressions
Incomplete expressions, such as the following:
IF %X = 10 OR %Y > 40 AND %A = %B WITH
produce this message:
M204.0052 ILLEGAL TERM
Compilation does not succeed and the procedure does not run.
Using expressions for value retrieval
You can use expressions for value retrieval in the following User Language statements, as described in the appropriate sections of this manual:
- Update statements (STORE RECORD, ADD, CHANGE, DELETE, INSERT)
- FILE RECORDS
- FIND
- FIND - POINT$ condition
- FIND - SFL$ and SFGE$ conditions
- FOR EACH RECORD IN ORDER BY
- FOR EACH RECORD WHERE
- FIND ALL VALUES
- FOR EACH VALUE
- FOR RECORD NUMBER
Expression types supported in User Language statements
The following table provides examples of the types of expressions that you can use to supply retrieval values for statements.
Expression type | Example |
---|---|
Function call | IN ?&FILE FD ORDER.DATE EQ VALUE($DATE(1,)) |
String concatenation | IN ?&FILE FD BIRTH.DATE EQ VALUE(%YYYY WITH %MM WITH %DD) |
Arithmetic operation | IN ?&FILE FD SALES.VALUE EQ VALUE(%ITEM.VALUE * %ITEM.SALES ) |
User Language construct | IN ?&FILE FD NUM.ORDERS EQ VALUE(COUNT IN FD.ORDERS) |
Boolean expression | IN ?&FILE FD ORDER.STATUS EQ VALUE(%STATUS IS LIKE 'A*') |
The following example shows these different types of expressions used as values.
Example
B %MM IS STRING LEN 2 %DD IS STRING LEN 2 %BASE.PREMIUM IS FLOAT %PCT.INCREASE IS FLOAT * * function call expression * PRINT 'FD1' FD1: IN CLIENTS FPC INCIDENT DATE EQ - VALUE($DATECHG('YYYYMMDD',$DATE(1,),-3169)) END FIND FR FD1 PAI PRINT END FOR * * string concatenation expression * PRINT 'FD2' %MM = '09' %DD = '17' FD2: IN CLIENTS FPC ANNIV DATE EQ VALUE(%MM WITH %DD) END FIND FR FD2 PAI PRINT END FOR * * arithmetic operation expression * PRINT 'FD3' %BASE.PREMIUM = 1280 %PCT.INCREASE = 1.25 FD3: IN CLIENTS FPC TOTAL PREMIUM EQ VALUE(%BASE.PREMIUM * %PCT.INCREASE) END FIND FR FD3 PAI FEO1: FEO VIN * * UL syntax expression * PRINT 'FD4' FD4: IN VEHICLES FPC VIN EQ VALUE(VALUE IN FEO1) END FIND FR FD4 PAI PRINT END FOR END FOR END FOR * * boolean expression * PRINT 'FD5' FD5: IN CLIENTS FPC INCIDENT EQ VALUE('T' WITH (%DD IS LIKE '1*')) END FIND FR FD5 PAI PRINT END FOR END
Operators
This section describes the use of four types of operators:
- Arithmetic
- Comparison
- Boolean
- WITH
See the previous section for a discussion of expressions, and the next section for a discussion of operands. See FIXED precision arithmetic for a more detailed discussion.
Arithmetic operators
Arithmetic operators lists the arithmetic operators:
+ | Addition |
---|---|
- | Subtraction, unary minus |
* | Multiplication |
/ | Division |
Order of operations
The arithmetic operators are used to compute the value of a %variable or they can be included in an expression. When an expression contains several arithmetic operations, the operations are performed in the order shown in Operator order of precedence. Operators of equal precedence are evaluated in order of appearance, from left to right. For example:
%RESULT = 8*7 + 4
sets %RESULT to 60.
Parentheses change the order of operations; expressions within parentheses are compiled first. For example:
4-5*2*3 = -26 (4-5)*(2*3) = -6 (4-(5*2))*3 = -18
Arithmetic overflow
An arithmetic overflow might occur during evaluation of a computation statement. If such an overflow occurs, the request is cancelled and an appropriate error message is issued.
Comparison operators
The following comparison operators are used to compare two objects, two strings, two numbers, or a string and a number:
Operator | Meaning |
---|---|
EQ, = | Equal |
NE, ¬= | Not equal |
GT, > | Greater than |
LT, < | Less than |
GE, >= | Greater than or equal to |
LE, <= | Less than or equal to |
IS [NOT] LIKE | Pattern matching equivalents |
IS [NOT] PRESENT | Field existence |
When a comparison operator is included in an expression, a value of 1 results if the stated relation between operands is true; if false, a value of 0, provided that one of the following conditions apply (using the expression %I = (%A<=%B) to illustrate):
- Either %A or %B (or both) is declared as FIXED or FLOAT.
- Either %A or %B (or both) is signed in the expression; for example,
%I = (+%A <=%B)
. - VTYPE = FLOAT or FIXED, and VLEN is greater than zero.
The resulting value returned from the expression might be invalid if all the following conditions apply:
- Neither %A nor %B is declared.
- The expression does not sign the variable.
- The system default for VTYPE is STRING and VLEN is greater than zero.
Notes:
- See the discussion about the conditional statement in Comparison operators for a description of these operators in conditional statements.
- The first character (
¬
) of the inequality test above is the EBCDIC "not sign", which has the hexadecimal value5f
.- For a description of the
IS [NOT] LIKE
clauses, see the syntax of Is Like patterns.
Boolean operators
Use the Boolean operators listed in the following table to modify or link together comparison expressions. (See the discussion about Boolean operators and conditional statements for information on comparisons.)
Operator | Meaning |
---|---|
NOT | The value of the comparison is reversed. |
AND | Both comparisons must be true. |
OR | Either comparison must be true. |
Boolean operators are not restricted to comparisons. They also can be used in the middle of expressions (for example, 1 AND 2).
WITH operator
WITH can be used in an expression to concatenate two strings. For example:
%A = '$' WITH TOTAL PREMIUM PRINT %A TO COLUMN 10
results in:
$550 $1092 $605
Operands
This section describes the use of four types of operands:
- %variables
- Quoted strings
- Numbers
- Fields
See also
Variables as operands
After you define a %variable, you can use it to change other %variables. For example:
%COUNT = %NUM
sets %COUNT, and:
%COUNT = %COUNT + 1
replaces the value of %COUNT by its former value plus 1.
Quoted strings
Examples of %variables set to quoted strings are provided here:
%NAME = 'TETLEY' %AGE = '53' %TITLE = 'QUARTERLY REPORT' %SPOUSE =
In the preceding example, %SPOUSE is a quoted string that has a length of 0.
Additional information about the use of quotation marks is provided in Quotation marks.
Numbers
A number used as the value of a %variable or as a term in an expression can be a string of digits containing an optional sign and an embedded decimal point.
For example:
3 +0.002 45.7 -37
The magnitude of the number is limited by the magnitude of the largest number that can be represented in a floating point number. Therefore the number's exponent (if the number is expressed in exponent notation) must be between 75 and -74.
Fields
Field values, referred to by field name, can be used in an assignment statement, but only inside a FOR EACH RECORD loop. To evaluate an expression, Model 204 uses the value of the field for the current record each time through the loop. For example:
FOR EACH RECORD IN FIND.RECS %PROFIT = %INCREASE - TOTAL PREMIUM PRINT %PROFIT END FOR
calculates profit from the data in each record and prints it. %PROFIT changes for each record.
In expressions, the values of most types of fields are treated as character strings. The values of fields defined with the FLOAT attribute are treated as numbers. If a field is missing from a record being processed, the value used is a null string.
FIXED precision arithmetic
An arithmetic operation where both operands are FIXED requires rules to determine the scale (maximum numbers of digits and decimal places) of the result.
Scale of intermediate results
Model 204 determines the scale of intermediate results (the number of decimal places) using the following rules.
Addition and subtraction
When an expression requires either addition or subtraction, the scale of the temporary variable containing the result equals the larger of the scales of the two operands. For example, the scale for the result of the following expression is 3:
12.345 + 3.6
If the result exceeds 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. If a 15 digit number cannot be produced even by dropping all decimal places, an overflow condition is indicated.
Multiplication
When an expression requires multiplication, the scale of the temporary variable containing the result is equal to the sum of the scales of the two operands. For example, the scale for the result of the following expression is 5 (3+2):
12.345 * 3.64
If the sum of the scales of the operands exceeds 9 or if the result is larger than 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. As with addition and subtraction, if the result has more than 15 digits with all decimal places discarded, an overflow condition is indicated.
Division
When an expression requires division, the scale of the temporary variable containing the result is equal to the larger of:
- 9
- the largest possible scale that fits in 15 digits
For example, the scale for the result of this expression is 9 (the calculated result is 3.529411764):
12 / 3.4
Causes of overflow conditions
The following situations are treated as overflow conditions:
- When the integer portion of any intermediate or final result is larger than 15 digits.
- For addition and multiplication, when the scale of the final result variable is so large that the integer portion of the result cannot fit into the maximum allotted size. For example:
BEGIN %A IS FIXED DP 0 %B IS FIXED DP 0 %C IS FIXED DP 9 %A = 999999 %B = 1 %C = %A + %B PRINT 'C = ' %C END *** M204.0542: EDIT COMPLETE - GO *** M204.0552: VARIABLE TOO SMALL FOR RESULT C = 0.000000000
Because the scale of the variable which contains the final result (%C) is 9, the integer portion of the result is limited to no more than 6 digits. Because the integer portion of the result requires 7 digits, an overflow condition is triggered.
This example illustrates that Model 204 takes into consideration the scale of the final result variable. The example below is identical to the one above except that the scale of %C is set to 8. The request executes successfully because this frees the required 7 digits for the integer portion of the result:
BEGIN %A IS FIXED DP 0 %B IS FIXED DP 0 %C IS FIXED DP 8 %A = 999999 %B = 1 %C = %A + %B PRINT 'C = ' %C END *** M204.0542: EDIT COMPLETE - GO C = 1000000.00000000
How Model 204 responds to overflow conditions
Overflowing to zero
When Model 204 detects an overflow condition, the intermediate result is set to 1015. Since this is a 16-digit number, it is illegal in User Language and tends to cause a cascade of overflow conditions in a complex expression, which can generate the following error message:
M204.0552: VARIABLE TOO SMALL FOR RESULT
The final result of the expression is usually 0, which lets you see that an overflow error might have occurred.
Overflowing to very large, obviously incorrect number
An exception to the rule of a 0 final result is the case where an overflow occurs in an intermediate step and the next step (whether intermediate or final) involves subtracting a value whose scale is 0 so that the result is less than 1015. In this case, you get a large, incorrect, result. For example:
BEGIN %X IS FIXED DP 0 %Y IS FIXED DP 0 %Z IS FIXED DP 0 %X = 10E13 %Y = 350000 %Z = 10 * (%X * %Y) WILL OVERFLOW AND BECOME 10E15 %X = (%X * %Y) - %Z PRINT 'X =' %X END *** M204.0542: EDIT COMPLETE - GO *** 1 M204.0563: ARITHMETIC OVERFLOW X = 999999999999990
VALUE IN, COUNT IN, and OCCURRENCE IN phrases
You can set a %variable value based on the following elements of a User Language request:
- VALUE IN phrase
A %variable can be set equal to a noted value, as illustrated below:
%DRIVER = VALUE IN NOTE.DRIVER
This phrase also can be included in an expression or used to include the current value in a FOR EACH OCCURRENCE or FOR EACH VALUE loop.
- COUNT IN phrase
A %variable can be set equal to the number of records counted, as in:
%COUNT = COUNT IN NO.OF.VINS
This phrase also can be included in an expression.
- OCCURRENCE IN phrase
A %variable can be set equal to the subscript value of the current occurrence of a field in a record, as in:
%OCCUR = OCCURRENCE IN INCIDENT.TYPE
where INCIDENT.TYPE is the statement label of a FOR EACH OCCURRENCE statement. This phrase also can be included in an arithmetic expression.
Conversions and significant digits
Numeric terms
The following expression terms are considered numeric:
- Literal (unquoted) numbers: -3, .0079
- COUNT IN phrases
- OCCURRENCE IN phrases
- Some functions (see User Language mathematical functions)
- Results of numeric expressions
- FIXED or FLOAT %variables
- FLOAT fields
Character terms
The following expression terms are considered character:
- Quoted strings: 'SMITH', '.0079'
- Non-FLOAT fields: NAME, ADDRESS
- VALUE IN phrases
- Some functions (see See Standard functions)
- STRING %variables
Conversion
In the expression AGE + 10, the value of the field AGE (character) is added to a literal number (numeric). Model 204 converts the value of AGE to a number. If the value is a proper number (for example, 5, -3.943, +.0003), the conversion is obvious; if not, the value is not a proper number (for example, FIVE, ", ABCD) or a number with too many digits, it is converted to a zero.
In the expression 'NUMBER' WITH -3.8, a quoted string is to be concatenated with a number. Model 204 first converts the number to a character string. In such a conversion, all decimal places are lost; the number is truncated to an integer and the result is NUMBER-3.
Significant digits in computations
User Language can accept as input to computations the largest floating point number that can be expressed in exponent notation and can produce results of that magnitude.
However, all results contain at most 15 significant decimal digits, with zeros in the low-order positions. Model 204 preserves 15 digits in all intermediate results, rounding each result to 15 digits before going on to the next intermediate calculation.
If the final result is assigned to a STRING %variable, that result is truncated on the right to the maximum length specified for the %variable.
Sample request using %variables
The following request illustrates an assignment statement. The request computes the total settlement amount for each claim type within a file. Output consists of a 2-column table, giving a total amount for each type as well as a grand total settlement amount.
For example:
BEGIN VARIABLES ARE STRING DP 2 SET HEADER 2 'TOTAL' TO COLUMN 34 SET HEADER 3 'CLAIM TYPE' - WITH 'SETTLEMENT AMOUNT' TO COLUMN 40 SET HEADER 4 NEW PAGE EACH.TYPE: FOR EACH VALUE OF CLAIM TYPE TYPE.MATCH: FIND ALL RECORDS FOR WHICH CLAIM TYPE = VALUE IN EACH.TYPE END FIND FOR EACH RECORD IN TYPE.MATCH %TOT = %TOT + SETTLEMENT AMOUNT END FOR PRINT VALUE IN EACH.TYPE AT COLUMN 6 - WITH %TOT TO COLUMN 36 %GRANDTOT = %GRANDTOT + %TOT %TOT = 0 END FOR SKIP 1 LINE %GRANDTOT = '$' WITH %GRANDTOT PRINT 'GRAND TOTAL:' WITH %GRANDTOT TO COLUMN 36 END
Note that the user resets the value of %TOT to 0 after each pass through the value loop. Because %variables retain their values until explicitly reset, the user is responsible for clearing %variables that are to be reused. Model 204 does not perform this type of housekeeping routine automatically.
The output resulting from the preceding request is:
TOTAL CLAIM TYPE SETTLEMENT AMOUNT O 52905.00 C 53310.00 L 51773.00 GRAND TOTAL: $157988.00
Using %variables in place of the NOTE statement
In most cases the NOTE statement can be replaced with an assignment statement to achieve the same results.
Example
In this example, POLICY NO is assigned to a variable rather than a NOTE statement:
BEGIN POL.HOLDERS: FIND ALL RECORDS FOR WHICH RECTYPE = POLICYHOLDER END FIND FOR EACH RECORD IN POL.HOLDERS %POLICY.NO = POLICY NO EACH.POL.NO: FIND ALL RECORDS FOR WHICH POLICY NO = %POLICY.NO RECTYPE = DRIVER END FIND FOR EACH RECORD IN EACH.POL.NO PRINT %POLICY.NO AND FULLNAME END FOR END FOR END
Caution: Some caution is required when substituting %variables for NOTE statement values. The NOTE statement retains up to 255 characters, while an undeclared %variable retains only the default length set by the VLEN parameter. If a %variable is used for a long field value, the length parameter for the %variable must be reset to avoid truncation.
Impact on STBL space
Another difference between %variables and NOTE statement values is the use of space in the system work area STBL. For more information on STBL, refer to STBL (character string table)."
Field name variables
Field name variables permit indirect reference to field names, thereby permitting many procedures and requests to be generalized without using dummy strings (refer to Dummy strings in procedures for a discussion). The actual field names used in a particular procedure or request are specified when the request is executed. Field name variables are extensions of the %variables described in the preceding section.
Syntax
A field name %variable is indicated in this format:
%%name
For example:
%%DISCOUNT
Using field name variables
During the evaluation phase of a request, a string value can be assigned to a %variable:
%DISCOUNT = 'DISCOUNT'
and that %variable can then be used in User Language statements where field names normally appear, as in this example:
ADD.REC: STORE RECORD %%DISCOUNT = .055 END STORE
A field name variable and a variable with identical names are actually the same variable. When the variable is used in %variable context (for example, on the left hand side of an assignment statement), it takes the usual %name form. If the same variable is used in a field name context (for example, to the left of an equal sign (=) in a FIND condition), it takes the %%name form. In the latter case, the value of the variable (when the FIND statement is evaluated) is used as the field name.
Example
BEGIN START.REQUEST: %A = $READ('ENTER FIELD NAME') IF.QUIT: IF %A EQ 'QUIT' THEN JUMP TO STOP.REQUEST END IF %B = $READ('ENTER VALUE') MATCH.SET: FIND ALL RECORDS FOR WHICH %%A = %B END FIND FOR EACH RECORD IN MATCH.SET PRINT.INFO: PRINT 'RECNO ' WITH RECNO - WITH %A AT COLUMN 15 AND %%A END FOR JUMP TO START.REQUEST STOP.REQUEST: PRINT 'END OF REQUEST' END
If the file consists of these two records:
RECNO = 1 RECNO = 2 AGE = 23 AGE = 1 WEIGHT = 146 WEIGHT = 23
and the user replies to the $READ prompts with:
AGE 23 WEIGHT 23 QUIT
The output from the request is:
RECNO 1 AGE 23 RECNO 2 WEIGHT 23 END OF REQUEST
The START.REQUEST and IF.QUIT statements use %A as a variable. When %A is used as a field name variable in the FIND condition of the MATCH.SET statement, it appears as %%A. In the PRINT.INFO statement, both %A and %%A are used. First the value of %A (the string value that represents the field name) is printed. Then %%A is used as a field name, printing the value of that field within the record.
Assigning values to field name variables
You need to be aware of the difference between the following statements:
FIELD.VAR: %A = EMPLOYEE NUM STRING.VAR: %A = 'EMPLOYEE NUM'
The FIELD.VAR statement assigns the value of the field named EMPLOYEE NUM from the current record to %variable A. The FIELD.VAR statement must appear within a FOR EACH RECORD loop.
In contrast, the STRING.VAR statement assigns the character string 'EMPLOYEE NUM' as the value of %variable A. If %variable A is to be used subsequently as a field name variable, it must contain a valid field name for the file(s) being examined by the request.
Subscripted field name variables
You can use subscripts with field name variables, as discussed in Subscripts. This is often useful in specifying indirect references to particular occurrences of multiply occurring fields. Any field name variable can be followed by a parenthesized expression. The value of this expression is used as a subscript that specifies the desired occurrence of the named field.
For example, the field name variable reference:
%%DISCOUNT(5)
refers to the fifth value of the field represented by the field name variable, %%DISCOUNT.
The evaluation of subscript expressions is subject to the rules of assignment to an integer discussed earlier in this section.
It is also possible for the field name variable being subscripted to be an element of an array. The format of such a reference is:
%%variable (a1 [, a2 [, a3] ]) (n)
where a1, a2, and a3 are the subscripts of the array, and n is the occurrence subscript. For example:
%%ITEM(3,5) (4)
indicates the fourth occurrence of the field. The actual value of the field name variable is saved as the element of the array, %ITEM, with subscripts (3,5).
Resolution of field types and levels
Some statements operate only on fields of a particular type. Such requirements usually are enforced when a request is compiled. The use of field name variables defers error checking until the request is evaluated and the values of the variables are known. The value of a field name variable is checked for the same errors as field names known at compilation time (a reference to an undefined field, an attempt to print an INVISIBLE field, a length error on a preallocated field, or a security access violation). If an error is detected the request evaluation is cancelled.
Possible file inconsistency
Cancellation of a request during a sequence of statement updates could leave a file in a logically inconsistent state.
This occurs if a change is made before an incorrect reference to a field name variable, and also before a dependent change is made. A request that stores records using field name variables for some fields, or a request that operates on fields with security levels, could leave a file in an inconsistent state if an error occurs for one or more of the fields. The result might be a record without some or all of its fields.
The field type and security level of a variable can be checked before updating by using the $DSCR, $FLSACC, and $FLSCHK functions described in See SOUL $functions.