Arithmetic Operators

The arithmetic operators and the operations they stand for are:

Operator     Operation
prefix + Plus
prefix – Minus
+ Addition
Subtraction
* Multiplication
/ Division
** Exponentiation

There are also compound assignment operators. These are:

+= -= *= /=

Each of the following pairs of statements are equivalent:

a = a + b;
a += b;
a = a - b ;
a -= b;
a = a * b;
a *= b;
a = a / b;
a /= b;

The arithmetic operators require arithmetic operands. Although these operands can be of different arithmetic types, all operations must be performed on objects of the same type. Pictured values are converted to fixed decimal values, but other nonarithmetic values must be converted to arithmetic values by one of the conversion built-in functions, such as BINARY, DECIMAL, FIXED, or FLOAT.

If the data types of two operands of an infix operator (other than **) differ, the operands are converted to a common arithmetic data type, as shown in the following table.

One Operand     Other Operand     Common Operand
fixed float float
binary decimal binary (for floating-point or integer result)
binary decimal decimal (for fixed-point noninteger result)

All arithmetic operations except for exponentiation are performed in the derived type of the two operands. (For the precision resulting from the conversion of an operand to its derived type, see the table in Arithmetic to Arithmetic Conversion.) Though two converted operands may have the same derived base and scale, they may each have different values for p and q (scale and base, respectively).

All arithmetic operations, including exponentiation, produce a result that has the same data type as the type in which the operations are performed. In all operations but exponentiation, the data type is derived.

If an arithmetic operation is performed in floating point, the precision of the result is the maximum of the precisions of the two operands for binary operators, and is equal to the precision of the operand for unary operators. If this is not the desired result precision, use the FLOAT() built–in function to increase the precision of one or both of the operands.

An exponentiation operation on floating-point decimal data is actually performed using the floating-point binary operation. Thus, the range of the operands and the result of the operation are limited to the ranges for floating-point binary numbers.

The remainder of this topic defines a series of rules, called fixed-point precision rules, which effectively allow the result of an expression to be formed by aligning the decimal points of the two operands to produce a fixed-point result. The number of digits in the result is always limited by the maximum number of digits allowed by the implementation for the result base; however, as many fractional digits as are allowed by the implementation are preserved, except for the result of divide. (For details on this implementation, see your Open PL/I User's Guide.) For divide, all integer quotient digits are preserved and as many fractional digits as can be allowed by the implementation are preserved.

The results of all arithmetic operations, except for exponentiation, always have a precision that is the maximum of the precisions of the converted operands.

The rules for determining the precision of the results of arithmetic expressions are as follows:

  1. Plus and minus produce a result whose data type is the same as the converted operand.
  2. Add and subtract of fixed-point values produce a fixed-point result whose base is the common base and whose precision is:
    FIXED(P,Q)±FIXED(R,S)

    and yields

    P=MIN(N,1+MAX(P-Q,R-S)+MAX(Q,S)) 
    Q=MAX(Q,S)

    where:

    N is the implementation's maximum allowed precision for fixed-point values of the result base (described in your Open PL/I User's Guide).

    (P,Q) is the converted precision of the first operand

    (R,S) is the converted precision of the second operand

  3. For integer operands (Q=0 and S=0), the result precision formula reduces to:
    FIXED(P,0)±FIXED(R,0)

    and yields

    P=MIN(N,1+MAX(P,R)) 
    Q=0
  4. Multiplication of fixed-point values produces a fixed-point result whose base is the common base and whose precision is:
    FIXED(P,Q)*FIXED(R,S)

    and yields

    P=MIN(N,P+R+1) Q=Q+S

    where:

    N is the implementation's maximum allowed precision for fixed-point values of the result base (described in your Open PL/I User's Guide).

    (P,Q) is the converted precision of the first operand,

    (R,S) is the converted precision of the second operand

  5. For integer operands (Q=0 and S=0), the result precision formula reduces to:
    FIXED(P,0)/FIXED(R,0)

    and yields

    P=MIN(N,P+R+1) 
    Q=0
  6. Division of fixed-point values is possible only if both operands are fixed decimal. The result is a fixed decimal value of precision:
    FIXED(P,Q)/FIXED(R,S)

    and yields

    P=N 
    Q=N-P+Q-S

    where:

    N is the maximum fixed-point decimal precision

    (P,Q) is the precision of the first operand

    (R,S) is the precision of the second operand

  7. For integer operands (Q=0 and S=0), the previous formula reduces to:
    FIXED(P,0)/FIXED(R,0)

    and yields

    P=N 
    Q=N-P

    The formula produces a result quotient that has sufficient precision for all integral digits of the quotient and as many fractional digits as are allowed by the implementation (for Open PL/I's limits, see your Open PL/I User's Guide).

  8. The result of a division operation may have a large fractional part, and in such instances, may not be able to be added or multiplied with another value because alignment of the decimal point with the other value produces a result that is too big for Open PL/I to support.
  9. The ADD, DIVIDE, and MULTIPLY built-in functions can be used to add, divide, and multiply fixed-point binary values, as well as fixed-point decimal values. These functions provide you with control over the result precision. See the section DECIMAL Function in the chapter Open PL/I Built-Ins.
  10. Exponentiation produces a result whose base, scale, and precision depends on the operands. The result is determined as follows:

    Case 1:

    If the first operand is fixed-point and the second operand is an integer constant whose value is Y, and if (P+1)*Y-1 does not exceed N, the result is a fixed-point value whose base is that of the first operand and whose precision is:

    FIXED(P,Q)**Y     /* Y is an integer constant */

    and yields

    P=(P+1)*Y-1 
    Q=Q*Y
    P<=N

    where N is the maximum precision allowed for fixed-point values of the base of the first operand, (P,Q) is the precision of the first operand, and Y is the value of the second operand.

    Case 2:

    If the second operand is a fixed-point integer value, but Case 1 does not apply, the result is a floating-point value whose base is the base of the first operand and whose precision is:

    P=MIN(N,P)

    where N is the maximum precision allowed for floating-point values of the resulting base and P is the precision of the first operand.

    Case 3:

    If neither Case 1 nor Case 2 applies, the result is a floating-point value having the common base and whose precision is:

    P=MIN(N,MAX(P,R))

    where N is the maximum precision allowed for floating values having the result base, P is the converted precision of the first operand, and R is the converted precision of the second operand.

  11. The result of exponentiation is normally the first operand raised to the power of the second operand. The following are exceptions to this general rule.

    Given X is the value of operand one and Y is the value of operand two:

    • If X = 0 and Y <= 0, ERROR is signaled.
    • If X< 0 and Case 1 does not apply, ERROR is signaled.
  12. For the addition, multiplication and division operations, and the AND, OR, MOD, MIN and MAX built-ins, if both operands are UNSIGNED FIXED BINARY, then the result is UNSIGNED FIXED BINARY.