Appendix D
Rules for Conversion of Data
This appendix provides details of the data type conversions that PL/I performs when assigning values to variables. The rules for conversions apply to the following:
D.1. Assignments to Arithmetic Variables
You can assign expressions of any computational type to arithmetic variables. Note, however, that the compiler may issue a warning message unless an explicit conversion function is used. The conversion rules are described in the following sections for each source type.
D.1.1. Arithmetic to Arithmetic Conversions
You can assign a source expression of any arithmetic type to a target variable of any arithmetic type. Note the following qualifications:
If the target is a variable of type FIXED BINARY or FIXED DECIMAL, then the FIXEDOVERFLOW condition is signaled when the source value has a larger number of integral digits than are specified in the precision of the target. If the target is a fixed-point binary variable, FIXEDOVERFLOW is signaled if the source value exceeds the storage allocated for the target.
If the target is a variable of type FIXED-POINT(p,q) and the source value has more than q fractional digits, then the excess fractional digits of the source are truncated, and no condition is signaled. If the source has fewer than q fractional digits, the source value is padded on the right with zeros.
If the target value is floating point and the absolute source value is too large to be represented by an OpenVMS VAX or OpenVMS Alpha floating-point type (see Chapter 10, Error Handling), then the OVERFLOW condition is signaled, and the value of the target is undefined. If the absolute source value is too small to be represented, the value zero is assigned to the target if the UNDERFLOW option is not enabled. If the UNDERFLOW option is enabled, the UNDERFLOW condition is signaled, and the value of the target is undefined.
D.1.2. Pictured to Arithmetic Conversions
In PL/I all pictured values have the associated attributes FIXED DECIMAL(p,q), where p is the total number of characters in the picture specification that specify decimal digits, and q is the total number of these digits that occur to the right of the V character. If the picture specification does not include a V character, then q is zero. This associated fixed-point decimal value is assigned to the target, following the rules for arithmetic to arithmetic conversion described in Section D.1.1, “Arithmetic to Arithmetic Conversions”.
D.1.3. Bit-String to Arithmetic Conversions
When a bit-string value is assigned to an arithmetic variable, PL/I treats the bit string as a nonnegative fixed-point binary value. If the converted value is greater than or equal to 231 for OpenVMS VAX or 263 for OpenVMS Alpha, then FIXEDOVERFLOW is signaled. The leftmost bit in the bit string (as output by PUT LIST) is the most significant bit in the fixed-point binary value, not its sign. If the bit string is null, the fixed-point binary value is zero. The intermediate fixed-point binary value is then converted to the target arithmetic type.
Note that a bit string interpreted as a fixed-point binary value changes its value when assigned to a bit-string variable of a different length. See the Endless PL/I for OpenVMS Reference Manual for further details.
D.1.4. Character String to Arithmetic Conversions
When a character string is assigned to an arithmetic value, PL/I interprets the string as an arithmetic constant and creates an intermediate numeric value based on the characters in the string. The string can contain any series of characters that describes a valid arithmetic constant. If it contains any invalid characters, the ERROR condition is signaled.
PL/I then converts the intermediate value to the data type of the target, following the rules for arithmetic to arithmetic conversions. In conversions to fixed point, FIXEDOVERFLOW is signaled if the character string specifies too many integral digits. Excess fractional digits are truncated without signaling a condition.
If the source character string is null or contains all spaces, the resulting arithmetic value is zero.
D.2. Assignments to Bit-String Variables
In the conversion of any data type to a bit string, PL/I first converts the source data item to an intermediate bit-string value. Then, based on the length of the target string, it performs one of the following:
If the length of the target bit-string value is greater than the length of the intermediate string, the target bit string (as represented by PUT LIST) is padded with zeros on the right.
If the length of the target bit-string value is less than the length of the intermediate string, the intermediate bit string (as represented by PUT LIST) is truncated on the right.
The following sections describe how PL/I arrives at the intermediate bit-string value for each data type.
D.2.1. Arithmetic and Pictured to Bit-String Conversions
In converting an arithmetic value to a bit-string value, PL/I first computes the absolute value of the arithmetic value, and then converts it to an integer of type FIXED BINARY with a maximum precision of 31 for OpenVMS VAX or 63 for OpenVMS Alpha. If this conversion results in an integer larger than the data type can accommodate, the FIXEDOVERFLOW condition is signaled; otherwise, each of the bits of the intermediate bit string represents a binary digit of n.
During the conversion, the sign of the arithmetic value and any fractional digits are lost. As a result, a value that contains only fractional digits (such as 0.2312) is converted to an all-zero bit string.
If an arithmetic value is assigned to a bit-string variable, and that variable is assigned to a second variable of different length, the effect is to multiply or divide the arithmetic value as a result of padding or truncating the bit string. See the Endless PL/I for OpenVMS Reference Manual for further details.
D.2.2. Character-String to Bit-String Conversions
PL/I can convert a character string of 0s and 1s to a bit string. Any character in the character string other than 0 or 1, including spaces, will signal the ERROR condition. If the source is a null character string, the intermediate string is a null bit string.
D.3. Assignments to Character-String Variables
In the conversion of any data type to a character string, PL/I first converts the source value to an intermediate character-string value. Then it performs one of the following:
If the length of the intermediate string is zero, a null string is assigned to the target.
If the target is a returns descriptor with an asterisk extent (as in RETURNS CHAR(*)), the intermediate string is assigned to the target.
If the intermediate string is shorter than the maximum length of the target, and the target has the VARYING attribute, it is assigned the value of the intermediate string without trailing spaces. If the target does not have the VARYING attribute, the string is padded with trailing spaces.
If the maximum length of the target character string is less than the length of the intermediate string, the intermediate string is truncated.
The following sections describe how PL/I arrives at the intermediate string for conversion of each data type. Examples show the intermediate and resulting values.
D.3.1. Arithmetic to Character-String Conversions
The manner in which PL/I converts the arithmetic item depends on the data type of the source, as described in the following subsections.
D.3.1.1. Conversion from Fixed-Point Binary or Decimal
If the source value is of type FIXED BINARY, PL/I first converts it to type FIXED DECIMAL. PL/I converts a value with attributes FIXED DECIMAL to an intermediate string with the numeric value right justified in the string. Following is a description of the format of the intermediate string:
If there are no fractional digits, the first two characters of the string are spaces. The last characters in the string are the digit characters representing all the digits in the integer; leading zeros are replaced by spaces except in the last position. If the integer is negative, a minus sign immediately precedes the first digit; if not, this position contains a space. At least one digit always appears in the last position in the string.
If there are no integral digits, the first three characters are (in order) an optional minus sign if the fraction is negative, the digit 0, and a decimal point. If the number is not negative, the first character is a space. The last characters in the string are all the fractional digits of the number.
If there are both integral and fractional digits, the first character is always a space. The last characters are all the fractional digits of the number and are preceded by a decimal point; the decimal point is always preceded by at least one digit, which may be 0; all integral digits appear before the decimal point, and leading zeros are replaced by spaces. A minus sign precedes the first integral digit if the number is negative; if not, then the minus sign is replaced by a space.
These rules may cause confusion if you do not take into account the leading spaces. In the following examples, the letter b represents a space:
DECLARE STRING1 CHARACTER (8), STRING2 CHARACTER (4); STRING1 = 283472.; /* intermediate string = 'bbb283472', STRING1 = 'bbb28347' */ STRING2 = 283472.; /* intermediate string = 'bbb283472', STRING2 = 'bbb2' */ STRING2 = -283472.; /* intermediate string = 'bb-283472', STRING2 = 'bb-2' */ STRING2 = -.003344; /* intermediate string = '-0.003344', STRING2 = '-0.0' */ STRING2 = -283.472; /* intermediate string = 'b-283.472', STRING2 = 'b-28' */ STRING2 = 283.472; /* intermediate string = 'bb283.472', STRING2 = 'bb28' */
D.3.1.2. Conversion from Floating-Point Binary or Decimal
If the source value is of type FLOAT BINARY, it is converted to FLOAT DECIMAL. For a value of type FLOAT DECIMAL(p), where p is less than or equal to 34, the intermediate string is of length p+6; this allows extra characters for the sign of the number, the decimal point, the letter E, the sign of the exponent, and the 2-digit exponent.
Note
For PL/I, if the value is a floating-point number of the type G-float, three characters are allocated to the exponent, and the length of the string is p+7. For Endless PL/I V3.9 for OpenVMS VAX only, if the value is of type H-float, four characters are allocated to the exponent, and the length of the string is p+8.
If the number is negative, the first character is a minus sign; otherwise, the first character is a space. The subsequent characters are a single digit (which may be 0), a decimal point, p-1 fractional digits, the letter E, the sign of the exponent (always + or -), and the exponent digits. The exponent field is of fixed length, and the zero exponent is shown as all zeros in the exponent field.
For example:
CONCH: PROCEDURE OPTIONS(MAIN); DECLARE OUT PRINT FILE; OPEN FILE(OUT) TITLE('CONCH.OUT'); PUT SKIP FILE(OUT) EDIT('''',25E25,'''') (A); PUT SKIP FILE(OUT) EDIT('''',-25E25,'''') (A); PUT SKIP FILE(OUT) EDIT('''',1.233325E-5,'''') (A); PUT SKIP FILE(OUT) EDIT('''',-1.233325E-5,'''') (A); END CONCH;
The program CONCH produces the following output:
' 2.5E+26' '-2.5E+26' ' 1.233325E-05' '-1.233325E-05'
The PUT statement converts its output sources to character strings, following the rules described in this section. Note that the output strings have been surrounded with apostrophes to make the spaces distinguishable. Also note that, in each case, the width of the quoted output field (that is, the length of the converted character string) is the precision of the floating-point constant plus 6.
D.3.2. Pictured to Character-String Conversions
If the source value is pictured, its internal, character-string representation is used without conversion as the intermediate character string.
D.3.3. Bit-String to Character-String Conversions
When PL/I converts a bit string to a character string, it converts each bit (as represented by PUT LIST) to a 0 or 1 character in the corresponding position of the intermediate character string.
If the bit string is a null string, the intermediate character string is also null.
D.4. Assignments to Pictured Variables
A source expression of any computational type can be assigned to a pictured variable. The target pictured variable has a precision (p), which is defined as the number of characters in its picture specification that specify decimal digits. It also has a scale factor (q), which is defined as the number of picture characters that specify digits and occur to the right of the V character in the picture specification. If there is no V character, or if all digit-specification characters are to the left of V, then q is zero.
The source expression is converted to a fixed-point decimal value v of precision (p,q), following the rules given in Section D.1, “Assignments to Arithmetic Variables” for conversion from the source data type to fixed decimal. This value is then edited to a character string s, as specified by the picture specification, and the value s is assigned to the pictured target.
When the value v is being edited to the string s, the ERROR condition is signaled if the value of v is less than zero and the picture specification does not contain one of the characters S, +, -, T, I, R, CR, or DB. The value of s is then undefined. FIXEDOVERFLOW is also signaled if the value v has more integral digits than are specified by the picture specification of the target.
D.5. Conversions Between Offsets and Pointers
Offset variables are given values by assignment from existing offset values or from conversion of pointer values. Pointer variables are given values by assignment from existing pointer values or from conversion of offset values.
The OFFSET built-in function converts a pointer value to an offset value. The POINTER built-in function converts an offset value to a pointer. These functions are described in the Endless PL/I for OpenVMS Reference Manual.
PL/I also automatically converts a pointer value to an offset value, and an offset value to a pointer value, in an assignment statement. The following assignments are valid:
pointer-variable = pointer-value;
offset-variable = offset-value;
pointer-variable = offset-variable;
offset-variable = pointer-value;
In the latter two cases, the offset variable must have been declared with an area reference.