An arithmetic operation is specified by combining operands with one of these operators:
+ - * / **
The plus sign and the minus sign can appear as prefix operators or as infix operators. All other arithmetic operators can appear only as infix operators. (Arithmetic operations can also be specified by the ADD, SUBTRACT, DIVIDE, and MULTIPLY built-in functions.)
Prefix operators can precede and be associated with any of the operands of an infix operation. For example, in the expression A*-B, the minus sign indicates that the value of A is multiplied by -1 times the value of B.
More than one prefix operator can precede and be associated with a single variable. More than one positive prefix operator has no cumulative effect, but two negative prefix operators have the same effect as a single positive prefix operator.
The two operands of an arithmetic operation can differ in type, base, mode, precision, and scale. When they differ, conversion takes place as described below. (For coded arithmetic operands, you can also determine conversions using Table 13. Each operand is converted to the type, base, and mode of the result. It is not necessarily converted to the result's precision and scale.)
Character operands are converted to FIXED DECIMAL(N,0). Bit operands are converted to FIXED BINARY(M,0). (Refer to Appendix. Limits for the maximums.) Numeric character operands are converted to DECIMAL with scale and precision determined by the picture-specification.
Graphic and widechar variables and strings are allowed in all computational contexts. If conversion is necessary, the rules followed are the same as for character.
The result of an arithmetic operation is always in coded arithmetic form. Type conversion is the only conversion that can take place in an arithmetic prefix operation.
If the bases of the two operands differ, the decimal operand is converted to binary.
If the modes of the two operands differ, the real operand is converted to complex mode by acquiring an imaginary part of zero with the same base, scale, and precision as the real part. The exception to this is in the case of exponentiation when the second operand (the exponent of the operation) is fixed-point real with a scaling factor of zero. In such a case, conversion is not necessary.
If only precisions and/or scaling factors vary, type conversion is not necessary.
If the scales of the two operands differ, the fixed-point operand is converted to floating-point scale. The exception to this is in the case of exponentiation when the first operand is of floating-point scale and the second operand (the exponent of the operation) is fixed-point with a scaling factor of zero, that is, an integer or a variable that has been declared with precision (p,0). In such a case, conversion is not necessary, but the result is floating-point.
If both operands of an exponentiation operation are fixed-point, conversions can occur in one of the following ways:
After any necessary conversion of the operands in an expression has been carried out, the arithmetic operation is performed and a result is obtained. This result can be the value of the expression, or it can be an intermediate result upon which further operations are to be performed, or a condition can be raised.
Table 13 and Table 14 show the attributes and precisions that result from various arithmetic operations.
Table 18 shows the attributes of the result for the special cases of exponentiation noted in the right-hand columns of Table 13 and Table 14.
On the z/OS platform, the choice of which set of instructions is used for a float calculation is determined by two compiler options:
So, under the FLOAT(NODFP) and DEFAULT(HEXADEC) options, all computations are done using the hexadecimal floating-point instructions, and variables declared IEEE will be converted to HEXADEC. But, under the FLOAT(NODFP) and DEFAULT(IEEE) options, all computations are done using the IEEE binary floating-point instructions, and variables declared HEXADEC will be converted to IEEE as necessary.
On all other platforms, float calculations are done using the IEEE binary floating-point instructions native to that platform.
Under the compiler option RULES(ANS), if one operand is scaled FIXED DECIMAL and the other is FIXED BINARY, the FIXED BINARY value is converted to FIXED DECIMAL. Table 15 shows the attributes and precisions that result for this case under compiler option RULES(ANS). For more information on the RULES compiler option, see the Programming Guide.
|
1st Operand (p1,q1) |
2nd Operand (p2,q2) |
Attributes of the Result for Addition, Subtraction, Multiplication, or Division |
Addition or Subtraction Precision |
Multipli- cation Precision |
Division Precision |
Attributes of the Result for Exponentiation |
|---|---|---|---|---|---|---|
|
FLOAT DECIMAL (p1) |
FLOAT DECIMAL (p2) |
FLOAT DECIMAL (p) |
p = MAX(p1,p2) |
FLOAT DECIMAL (p) (unless special case C applies) p = MAX(p1,p2) |
||
|
FLOAT DECIMAL (p1) |
FLOAT DECIMAL (p2,q2) |
|||||
|
FIXED DECIMAL (p1,q1) |
FLOAT DECIMAL (p2) |
|||||
|
FLOAT BINARY (p1) |
FLOAT BINARY (p2) |
FLOAT BINARY (p) |
FLOAT BINARY (p) (unless special case C applies) p = MAX(p1,p2) |
|||
|
FLOAT BINARY (p1) |
FIXED BINARY (p2,q2) |
|||||
|
FIXED BINARY (p1,q1) |
FLOAT BINARY (p2,q2) |
|||||
|
FIXED DECIMAL (p1,q1) |
FLOAT BINARY (p2) |
FLOAT BINARY (p) |
p = MAX( CEIL(p1*3.32),p2) |
FLOAT BINARY (p) (unless special case A or C applies) p = MAX( CEIL(p1*3.32),p2) |
||
|
FLOAT DECIMAL (p1) |
FLOAT BINARY (p1,q2) |
|||||
|
FLOAT DECIMAL (p1) |
FLOAT BINARY (p2) |
|||||
|
FIXED BINARY (p1,q1) |
FLOAT DECIMAL (p2) |
FLOAT BINARY (p) |
p = MAX(p1,CEIL(p2*3.32)) |
FLOAT BINARY (p) (unless special case B or C applies) p = MAX( p1,CEIL(p2*3.32)) |
||
|
FLOAT BINARY (p1) |
FIXED DECIMAL (p2,q2) |
|||||
|
FLOAT BINARY (p1) |
FLOAT DECIMAL (p2) |
|||||
|
Notes:
|
|
1st Operand (p1,q1) |
2nd Operand (p2,q2) |
Attributes of the Result for Addition, Subtraction, Multiplication, or Division |
Addition or Subtraction Precision |
Multipli- cation Precision |
Division Precision |
Attributes of the Result for Exponentiation |
|---|---|---|---|---|---|---|
|
FIXED DECIMAL (p1,0) |
FIXED DECIMAL (p2,0) |
FIXED DECIMAL (p,q) |
p = 1 +MAX(p1,p2) q = 0 |
p = 1 +p1+p2 q = 0 |
p = N q = N-p1 |
FLOAT DECIMAL (p) (unless special case A applies) p = MAX(p1,p2) |
|
FIXED BINARY (p1,0) |
FIXED BINARY (p2,0) |
FIXED BINARY (p,0) |
p = 1 +MAX(p1-q1, p2-q2) +q q = 0 |
p = 1+p1 +p2 q = 0 |
p = M q = 0 |
FLOAT BINARY (p) (unless special case B applies) p = MAX(p1,p2) |
|
FIXED DECIMAL (p1,0) |
FIXED BINARY (p2,0) |
FIXED BINARY (p,0) |
p = 1 +MAX(r,p2) q = 0 |
p = 1 +r+p2 q = 0 |
p = M q = 0 |
FLOAT BINARY (p) (unless special case A applies) p = MAX(CEIL (p1*3.32 ),p2) |
|
FIXED BINARY (p1,0) |
FIXED DECIMAL (p2,0) |
FIXED BINARY (p,0) |
p = 1 +MAX(p1,t) q = 0 |
p = 1 +p1+t q = 0 |
p = M q = 0 |
FLOAT BINARY (p) (unless special case B applies) p = MAX(CEIL (p1*3.32 ),p2) |
|
M is the maximum precision for FIXED BINARY. N is the maximum precision for FIXED DECIMAL. r = 1 + CEIL(p1*3.32) s = CEIL(ABS(q1*3.32)) * SIGN(q1) |
t = 1 + CEIL(p2*3.32) u = CEIL(ABS(q2*3.32)) * SIGN(q2) v = CEIL(p2/3.32) w = CEIL(p1/3.32) |
|
Notes:
The scaling factor must be in the range -128 through +127. |
|
1st Operand (p1,q1) |
2nd Operand (p2,q2) |
Attributes of the Result for Addition, Subtraction, Multiplication, or Division |
Addition or Subtraction Precision |
Multipli- cation Precision |
Division Precision |
Attributes of the Result for Exponentiation |
|---|---|---|---|---|---|---|
|
FIXED DECIMAL (p1,q1) |
FIXED DECIMAL (p2,q2) |
FIXED DECIMAL (p,q) |
p = 1 + MAX(p1-q1, p2-q2) +q q = MAX(q1,q2) |
p = 1 +p1+p2 q = q1+q2 |
p = N q = N-p1+q1-q2 |
FLOAT DECIMAL (p) (unless special case A applies) p = MAX(p1,p2) |
|
FIXED DECIMAL (p1,q1) |
FIXED BINARY (p2,0) |
FIXED DECIMAL (p,q) |
p = 1 +MAX(p1- q1,v) +q q = q1 |
p = 1 +p2+v q = q1 |
p = N q = N-q1 |
FLOAT BINARY (p) (unless special case A applies) p = MAX(CEIL (p1*3.32 ),p2) |
|
FIXED BINARY (p1,0) |
FIXED DECIMAL (p2,q2) |
FIXED DECIMAL (p,q) |
p = 1 +MAX(p2- q2,w) +q q = q2 |
p = 1 +p2+w q = q1 |
p = N q = N-q2 |
FLOAT BINARY (p) (unless special case B applies) p = MAX(CEIL (p1*3.32 ),p2) |
|
M is the maximum precision for FIXED BINARY. N is the maximum precision for FIXED DECIMAL. r = 1 + CEIL(p1*3.32) s = CEIL(ABS(q1*3.32)) * SIGN(q1) |
t = 1 + CEIL(p2*3.32) u = CEIL(ABS(q2*3.32)) * SIGN(q2) v = CEIL(p2/3.32) w = CEIL(p1/3.32) |
|
Notes:
The scaling factor must be in the range -128 through +127. |
|
1st Operand (p1,q1) |
2nd Operand (p2,q2) |
Attributes of the Result for Addition, Subtraction, Multiplication, or Division |
Addition or Subtraction Precision |
Multipli- cation Precision |
Division Precision |
Attributes of the Result for Exponentiation |
|---|---|---|---|---|---|---|
|
FIXED DECIMAL (p1,q1) |
FIXED DECIMAL (p2,q2) |
FIXED DECIMAL (p,q) |
p = 1 +MAX(p1-q1, p2-q2) +q q = MAX(q1,q2) |
p = 1 +p1+p2 q = q1+q2 |
p = N q = N-p1+q1-q2 |
FLOAT DECIMAL (p) (unless special case A applies) p = MAX(p1,p2) |
|
FIXED BINARY (p1,q1) |
FIXED BINARY (p2,q2) |
FIXED BINARY (p,q) |
p = 1 +MAX(p1-q1, p2-q2) +q q = MAX(q1,q2) |
p = 1 +p1+p2 q = q1+q2 |
p = M q = M-p1 +q1-q2 |
FLOAT BINARY (p) (unless special case B applies) p = MAX(p1,p2) |
|
FIXED DECIMAL (p1,q1) |
FIXED BINARY (p2,q2) |
FIXED BINARY (p,q) |
p = 1 +MAX(r-s, p2-q2)+q q = MAX(s,q2) |
p = 1+r +p2 q = s+q2 |
p = M q = M-r +s-q2 |
FLOAT BINARY (p) (unless special case A applies) p =MAX( CEIL((p1*3.32 ),p2) |
|
FIXED BINARY (p1,q1) |
FIXED DECIMAL (p2,q2) |
FIXED BINARY (p,q) |
p = 1 +MAX(p1- q1,t-u) +q q = MAX(s,q1,u) |
p = 1 +p1+t q = q1+u |
p = M q = M-p1 +q1-u |
FLOAT BINARY (p) (unless special case B applies) p = MAX(p1, CEIL(p2*3.32)) |
|
M is the maximum precision for FIXED BINARY. N is the maximum precision for FIXED DECIMAL. r = 1 + CEIL(p1*3.32) s = CEIL(ABS(q1*3.32)) * SIGN(q1) |
t = 1 + CEIL(p2*3.32) u = CEIL(ABS(q2*3.32)) * SIGN(q2) v = CEIL(p2/3.32) w = CEIL(p1/3.32) |
|
Notes:
The scaling factor must be in the range -128 through +127. |
A * B + C
The operation A * B is performed first, to give an intermediate result. Then the value of the expression is obtained by performing the operation (intermediate result) + C.
PL/I gives the intermediate result attributes the same way it gives attributes to any variable. The attributes of the result are derived from the attributes of the two operands (or the single operand in the case of a prefix operation) and the operator involved. The way the attributes of the result are derived is further explained under Targets.
The ADD, SUBTRACT, MULTIPLY, and DIVIDE built-in functions allow you to override the implementation precision rules for addition, subtraction, multiplication, and division operations.
FIXED division can result in overflows or truncation. For example, the result of evaluating the expression:
25+1/3
is undefined and the FIXEDOVERFLOW condition is raised because FIXED division results in a value of maximum implementation defined precision.
For the following expression, however:
25+01/3
The result is 25.3333333333333 (when the maximum precision is 15) because constants have the precision with which they are written. The results of the two evaluations are reached as shown in Table 17:
|
Item |
Precision |
Result |
|---|---|---|
|
1 3 1/3 25 25+1/3 |
(1,0) (1,0) (15,14) (2,0) (15,14) |
1 3 0.33333333333333 25 undefined (truncation on left; FIXEDOVERFLOW is raised when the maximum precision is 15) |
|
01 3 01/3 25 25+01/3 |
(2,0) (1,0) (15,13) (2,0) (15,13) |
01 3 00.3333333333333 25 25.3333333333333 |
The PRECISION built-in function can also be used. For example:
25+prec(1/3,15,13)
The following table describes how exponentiation is handled in PL/I.
|
Case |
First Operand |
Second Operand |
Attributes of Result |
|---|---|---|---|
|
FIXED DECIMAL (p1,q1) |
Integer with value n |
FIXED DECIMAL (p,q) (provided p <= N) where p = (p1 + 1)*n-1 and q = q1*n |
|
|
B |
FIXED BINARY (p1,q1) |
Integer with value n |
FIXED BINARY (p,q) (provided p <= M) where p = (p1 + 1)*n-1 and q = q1*n |
|
C |
FLOAT (p1) |
FIXED (p2,0) |
FLOAT (p1) with base of first operand |
|
Special cases of x**y in real/complex modes:
|
|||