Arithmetic

6.7 Arithmetic

To perform arithmetic calculations there are two ways of going about doing this: using the ADD, SUBTRACT, MULITPLY, DIVIDE verbs, or using the COMPUTE verb as seen already. The formats for the first group are as follows: [square brackets indicate optional words]

 ADD {identifier-1 or literal}... TO {identifier-2 or literal}...
       [GIVING {identifier-3}]
       [NOT] [ON SIZE ERROR {statements}]
 [END-ADD]
Examples:
ADD NUM-A TO NUM-B GIVING NUM-TOTAL-1
ADD NUM-A, 20 TO NUM-B GIVING NUM-TOTAL-2
ADD 3 TO NUM-TOTAL-3
When the word GIVING is not used (as in the third example) the identifier that follows 'TO' is where the result of the addition. This also applies to SUBTRACT and MULTIPLY. ON SIZE ERROR is a conditional, whereby if the result of the calculation is larger than the PIC description (i.e. the result is truncated either at the leading end or the decimal places). On such an occasion a series of statements can be executed. The use of ON SIZE ERROR means that a scope terminator is required (END-ADD). The second example adds both NUM-A and 20 to NUM-B.

 
 SUBTRACT {identifier-1 or literal}... FROM {identifier-2 or literal}...
       [GIVING {identifier-3}]
       [NOT] [ON SIZE ERROR {statements}]
 [END-SUBTRACT]
Examples:
SUBTRACT 200 FROM NUM-C GIVING NUM-D
     ON SIZE ERROR DISPLAY 'NUM-D is out of range'
END-SUBTRACT
SUBTRACT NUM-F FROM 20       ** this won't work! **
The second example is illegal because, in the absence of a receiving identifier after GIVING, the result of the subtraction has nowhere to go (20 is a literal). The same would apply to ADD and MULTIPLY.

 
 MULTIPLY {identifier-1 or literal}... BY {identifier-2 or literal}...
       [GIVING {identifier-3}][ROUNDED]
       [NOT] [ON SIZE ERROR {statements}]
 [END-MULTIPLY]
Examples:
MULTIPLY NUM-G BY 20 GIVING NUM-F
MULTIPLY 20 BY NUM-G


 DIVIDE {identifier-1 or literal} BY {identifier-2 or literal}...
       GIVING {identifier-3} [ROUNDED] [REMAINDER {identifier-4}]
       [NOT] [ON SIZE ERROR {statements}]
 [END-DIVIDE]
Examples:
DIVIDE NUM-H BY 3 GIVING NUM-I REMAINDER NUM-REMAIN
DIVIDE NUM-Y BY 3 GIVING NUM-K ROUNDED
The DIVIDE statement differs from the previous 3 in that GIVING is required. Also, the remainder of the division (e.g. 7 divided by 3 equals 3 remainder 1) can be stored in an identifier. The ROUNDED option, which is also available for the MULTIPLY statement, will round to the nearest significant decimal place, defined by the PIC clause. E.g.:


000100 77 NUM-A  PIC 99 VALUE 10.
000200 77 NUM-B  PIC 9V99.
  :
002000      DIVIDE NUM-A BY 3 GIVING NUM-B
002010           ON SIZE-ERROR DISPLAY 'RESULT IS TRUNCATED'
002020      END-DIVIDE
002030
002040      DIVIDE NUM-A BY 3 GIVING NUM-B ROUNDED
002050           ON SIZE-ERROR DISPLAY 'RESULT IS TRUNCATED'
002020      END-DIVIDE


The first DIVIDE statement will result in a size error (20 / 3 = 6.66666..) as NUM-B will contain 6.66 but will have truncated the rest. This does not apply to the second DIVIDE statement since it has been rounded to fit the pic description 9V99, and so in this case NUM-B will contain 6.67.

 DIVIDE {identifier-1 or literal} INTO {identifier-2 or literal}...
       GIVING {identifier-3} [ROUNDED] [REMAINDER {identifier-4}]
       [NOT] [ON SIZE ERROR {statements}]
 [END-DIVIDE]
Examples:
DIVIDE 3 INTO NUM-Y GIVING NUM-K ROUNDED
This differs from the previous DIVIDE statement only in the order of numerator and denominator (both mean NUM-Y / 3).

 

COMPUTE

As previously seen in earlier sections, COMPUTE can be used to do arithmetic calculations. The format is:

COMPUTE {identifier-1} [ROUNDED] = arithmetic expression
     [NOT] [ON SIZE ERROR {statements}] [END-COMPUTE]


with the operations:

+     add
-     subtract
*     multiply
/     divide
**    to the power of


Note that brackets need to be used for complex calculations where signs have presidence over each other, for example: 2 + 3 * 2 equals 8 (and not 10) since 3 * 2 is calculated before the addition. Remember your school maths lessons (BROMDAS or something).