Previous | Contents | Index |
The relational, or comparison, operators test the relationship of two operands; the result is always a Boolean value (that is, a bit string of length 1). If the comparison is true, the resulting value is <BIT_STRING>(1)B; if the comparison is false, the resulting value is <BIT_STRING>(0)B. The relational operators are all infix operators. The following table describes all the relational operators:
Operator | Operation |
---|---|
< | Less than |
^< | Not less than |
<= | Less than or equal to |
= | Equal to |
^= | Not equal to |
>= | Greater than or equal to |
> | Greater than |
^> | Not greater than |
Note that PL/I recognizes the tilde symbol (~) as synonymous with the circumflex (^).
Relational operators compare any of the following data types: arithmetic (decimal or binary); bit-string; character-string; and entry, pointer, label, or file data. Specific results of operations on each type of data are elaborated below. The following general rules apply:
Arithmetic and picture operands are compared algebraically. If the
operands have a different base, scale, or precision, PL/I converts them
according to the rules for arithmetic operand conversion.
6.2.3.2 Bit-String Comparisons
When two bit strings are compared, they are compared bit by bit from
the most significant bit to the least significant bit (as represented
by PUT LIST). If the operands have different lengths, PL/I extends the
smaller operand with zeros in the direction of the least significance.
Null bit strings are equal.
6.2.3.3 Character-String Comparisons
When two character strings are compared, they are compared character by character in a left-to-right order. The comparison is based on the ASCII collating sequence. The ASCII characters are the first 128 characters of the DEC Multinational Character Set, which is in Appendix B.
Note the following characteristics of the collating sequence:
If the operands do not have the same length, PL/I extends the smaller
operand on the right with blanks for the comparison. Either or both of
the strings can have the attribute VARYING; PL/I uses the current
length of a varying character string when it makes the comparison. Null
character strings are equal.
6.2.3.4 Comparing Noncomputational Data
Only the following operators are valid, or meaningful, for comparisons of any of the noncomputational data types except areas (condition, entry, file, label, offset, and pointer):
Operator | Operation |
---|---|
= | Equal |
^= | Not equal |
The results of the comparisons provide the information indicated below for each data type.
Condition Data
Two condition values are equal if they identify the same condition values.Entry Data
Two entry values are equal if they identify the same entry point in the same block activation of a procedure.File Data
Two values defined with the FILE attribute are equal if they identify the same file constant.Label Data
Two label values are equal if they identify the same statement in the same block activation.A label that identifies a null statement is not equal to the label of any other statement.
Offset Data
Two offset values are equal if they identify the same storage location or if they are both null.Pointer Data
Two pointer values are equal if they identify the same storage location or if they are both null.
The concatenation operator produces a single string from two strings specified as operands. The concatenation operator is two vertical bars (||).
The operands must both be character strings or both be bit strings. (If not, the appropriate conversion is performed, and you get a warning message about the conversion. The result of the operation is a string of the same type as the operands.
CONCAT: PROCEDURE OPTIONS(MAIN); DECLARE OUTFILE STREAM OUTPUT PRINT FILE; PUT FILE(OUTFILE) SKIP LIST('ABC'||'DEF'); PUT FILE(OUTFILE) SKIP LIST('001'B||'110'B); PUT FILE(OUTFILE) SKIP LIST((3)'001'B||'07'B3); END CONCAT; |
The program CONCAT writes the following output to the file OUTFILE.DAT:
ABCDEF '001110'B '001001001000111'B |
Note that the exclamation point can be used in place of the vertical
bar, for compatibility with other PL/I implementations.
6.3 Precedence of Operators and Expression Evaluation
The precedence, or priority, of operators defines the order in which expressions are evaluated when they contain more than one operator. Table 6-2 gives the priority of PL/I operators. Low numbers indicate high priority. For example, the exponentiation operator (**) has the highest priority (1), so it is performed first, and the OR ELSE operator (|:) has the lowest priority (9), so it is performed last.
Operator | Priority | Left/Right Associative | Order of Evaluation |
---|---|---|---|
() | 0 | N/A | deepest first |
** | 1 | right | left to right |
+ (prefix) | 1 | N/A | N/A |
- (prefix) | 1 | N/A | N/A |
^ (prefix) | 1 | N/A | N/A |
* | 2 | left | left to right |
/ | 2 | left | left to right |
+ (infix) | 3 | left | left to right |
- (infix) | 3 | left | left to right |
|| | 4 | left | left to right |
> | 5 | left | left to right |
< | 5 | left | left to right |
^> | 5 | left | left to right |
^< | 5 | left | left to right |
= | 5 | left | left to right |
^= | 5 | left | left to right |
<= | 5 | left | left to right |
>= | 5 | left | left to right |
& | 6 | left | left to right |
| | 7 | left | left to right |
^ (infix) | 7 | left | left to right |
&: | 8 | left | left to right across entire expression |
|: | 9 | left | left to right across entire expression |
Expressions are evaluated from left to right, with the following qualifications:
A |: B &: C |
(A |: (B &: C)) |
A & USER_FUNCTION(ALPHA,BETA) |
A + B + FUNC(I) + C |
Conversion is the changing of a data item from one data type to another. Data conversion in PL/I takes place in many contexts, not all of them obvious ones. Program results that seem improper may in fact be caused by data conversion at some point in the program's execution. This section discusses the following topics:
PL/I can perform data conversions in the following contexts:
If an attempt is made to assign a value to a target for which there is no defined conversion, the compiler generates a diagnostic message. For example:
F = '133.45'; |
F = 'ABCD'; |
Table 6-3 illustrates the contexts in which PL/I performs conversions. The table also lists the built-in conversion functions, such as BINARY and CHARACTER, which you can use when you want to explicitly indicate a conversion and to specify such characteristics as the precision or string length of the converted result.
Context | Conversion Performed |
---|---|
target = expression; | In an assignment statement, the given expression is converted to the data type of the target. |
entry-name
RETURNS (attribute...); . . . |
In a RETURN statement, the specified value is converted to the data type specified by the RETURNS option on the PROCEDURE or ENTRY statement. |
RETURN (value); | |
x + y
x - y x * y x / y x**y x||y x & y x | y x&:y x|:y x ^ y x > y x < y x = y x^=y |
In any expression, if operands do not have the required data type, they are converted to a common data type before the operation. For most operators, the data types of all operands must be identical. A warning message is issued in the case of a concatenation conversion. |
BINARY (expression)
BIT (expression) CHARACTER (expression) DECIMAL (expression) DECODE (expression) ENCODE (expression) FIXED (expression) FLOAT (expression) OFFSET (variable) POINTER (variable) |
PL/I provides built-in functions that perform specific conversions. |
PUT LIST (item,...); | Items in a PUT LIST statement are converted to character-string data. |
GET LIST (item,...); | Character-string input data is converted to the data type of the target item. |
PAGESIZE (expression)
LINESIZE (expression) SKIP (expression) LINE (expression) COLUMN (expression) format items A, B, E, F, and X TAB (expression) |
Values specified for various options to PL/I statements must be converted to integer values. |
DO control-variable... | Values are converted to the attributes of the control variable. |
parameter | Actual parameters are converted to the type of the formal parameter, if necessary. |
INITIAL attribute | Initial values are converted to the type of the variable being initialized. |
Even though arithmetic operands can be of different arithmetic types, all operations will be performed on objects of the same type. Any set of operands of different arithmetic types has an associated derived type, as follows:
Table 6-4 gives the derived data type for two arithmetic operands of different types. (Note that the types derived from FIXED DECIMAL in Table 6-4 are also derived when one operand is pictured.)
Type of Operand 1 | Type of Operand 2 | Derived Type |
---|---|---|
FIXED BINARY | FLOAT BINARY | FLOAT BINARY |
FIXED BINARY | FLOAT DECIMAL | FLOAT BINARY |
FIXED DECIMAL | FLOAT DECIMAL | FLOAT DECIMAL |
FIXED DECIMAL | FLOAT BINARY | FLOAT BINARY |
FIXED BINARY | FIXED DECIMAL | FIXED BINARY |
Table 6-5 gives the precision resulting from the conversion of an operand to its derived type. The values p and q are known as the converted precision of an operand and are based on the values p and q of the source operand.
Target Data Type | Binary Fixed Source1 | Decimal Fixed Source1 | Binary Float Source1 | Decimal Float Source1 |
---|---|---|---|---|
Binary Fixed |
p
q |
min(ceil(p*3.32)+1,31) min(ceil(q*3.32),31) |
N/A
N/A |
N/A
N/A |
Decimal Fixed |
min(ceil(p/3.32)+1,31)
max(0,min(ceil(q*3.32),31)) |
p
q |
N/A
N/A |
N/A
N/A |
Binary Float |
OpenVMS VAX:
min(p,113) |
min(ceil(p*3.32),113) |
p |
min(ceil(p*3.32), 113) |
OpenVMS Alpha:
min(p,53) |
min(ceil(p*3.32),53) |
p |
min(ceil(p*3.32), 53) |
|
Decimal Float |
OpenVMS VAX:
min(ceil(p/3.32),34) |
min(p,34) |
min(ceil(p/3.32),34) |
p |
OpenVMS Alpha:
min(ceil(p/3.32),15) |
min(p,15) |
min(ceil(p/3.32),15) |
p |
All arithmetic operations except exponentiation are performed in the derived type of the two operands. Exponential operations are performed in a data type that is based on the derived type of the operands. All operations, including exponentiation, have results of the same type as that in which they are performed.
The result of an arithmetic operation can be assigned to a target variable of any computational type. The result is converted to the target type, following the rules in Section 6.4.5.
Previous | Next | Contents | Index |