Kednos PL/I for OpenVMS Systems
Reference Manual


Previous Contents Index

6.2.3 Relational Operators

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:

6.2.3.1 Arithmetic Comparisons

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.

6.2.4 Concatenation Operator

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.

Examples


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.

Table 6-2 Precedence of Operators
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:

6.4 Data Type Conversion of Operands and Expressions

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:

6.4.1 Contexts in which PL/I Converts Data

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'; 
If F is a variable with the attributes FIXED DECIMAL (5,2), then the statement assigns the numeric value 133.45 to F, as expected, although the compiler issues a WARNING message about the implicit conversion, stating that the constant 133.45 has been converted to a FIXED DECIMAL target. The warning does not prevent you from linking and running the program. However, note the following example:


F = 'ABCD'; 
This statement results not only in a compiler WARNING message, but if you go on to link and run the program, you receive a CONVERSION condition, which will normally be fatal unless it is handled with an ON CONVERSION ON-unit.

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.

Table 6-3 Contexts in Which PL/I Converts Data
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.

6.4.2 Derived Data Types for Arithmetic Operations

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.)

Table 6-4 Derived Data Types
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.

Table 6-5 Converted Precision as a Function of Target and Source Attributes
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


1The constant 3.32 is an approximation of log2(10), the number of bits required to represent a decimal digit.

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