Arithmetic Verbs

COMPUTE operators: + - * / ** and parentheses.

13.1 The five verbs

COMPUTE operators: + - * / ** and parentheses. Intrinsic functions can appear in expressions.

ADD A TO B                      *> B = B + A
           ADD A B C TO D                  *> D = D + A + B + C
           ADD A TO B GIVING C             *> C = A + B
           SUBTRACT A FROM B               *> B = B - A
           SUBTRACT A B FROM C GIVING D    *> D = C - A - B
           MULTIPLY A BY B                 *> B = A * B
           MULTIPLY A BY B GIVING C        *> C = A * B
           DIVIDE A INTO B                 *> B = B / A
           DIVIDE B BY A GIVING C          *> C = B / A
           DIVIDE B BY A GIVING Q REMAINDER R
           COMPUTE C = (A + B) * 2 / D ** 2

13.2 ROUNDED and ON SIZE ERROR

Without ROUNDED, extra decimal digits are truncated. ON SIZE ERROR is raised when the result does not fit the receiving field or on division by zero; when it triggers, the receiving field is left unchanged. Without it, the result is silently truncated (division by zero causes an abend on z/OS).

COBOL 2002/2014 add rounding modes: ROUNDED MODE IS NEAREST-EVEN (banker's rounding), NEAREST-AWAY-FROM-ZERO (the default for ROUNDED), TRUNCATION, AWAY-FROM-ZERO, TOWARD-GREATER, TOWARD-LESSER, NEAREST-TOWARD-ZERO, PROHIBITED (GnuCOBOL supports these; check IBM support per release).

01  WS-PRICE         PIC 9(5)V99 VALUE 19.99.
       01  WS-QTY           PIC 9(3)    VALUE 3.
       01  WS-TAX-RATE      PIC V9(4)   VALUE .0825.
       01  WS-TAX           PIC 9(5)V99.
       01  WS-TOTAL         PIC 9(3)V99.
      * ...
           COMPUTE WS-TAX ROUNDED = WS-PRICE * WS-QTY * WS-TAX-RATE
      *    59.97 * 0.0825 = 4.947525 -> ROUNDED -> 4.95 (else 4.94)

           COMPUTE WS-TOTAL = WS-PRICE * WS-QTY * 100
               ON SIZE ERROR
                   DISPLAY "Total too large for WS-TOTAL"
               NOT ON SIZE ERROR
                   DISPLAY "Total OK"
           END-COMPUTE

13.3 Intermediate results

COBOL computes intermediate results with enough precision for most business formulas, but very long chains of divisions can lose digits. Rules of thumb:

Multiply before you divide: COMPUTE X = A * 100 / B, not A / B * 100.

Make receiving fields large enough; use ROUNDED on the *final* result only. IBM ARITH(EXTEND) raises the maximum precision from 18 to 31 digits.

13.4 Example: loan payment

Expected monthly payment: about $1,580.17. (The intrinsic FUNCTION ANNUITY(rate, periods) computes the same factor — Chapter 20.)

IDENTIFICATION DIVISION.
       PROGRAM-ID. LOANPMT.
      * Monthly payment = P * r / (1 - (1 + r) ** -n)
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-PRINCIPAL      PIC 9(7)V99   VALUE 250000.00.
       01  WS-ANNUAL-RATE    PIC 9V9(6)    VALUE 0.065.
       01  WS-YEARS          PIC 99        VALUE 30.
       01  WS-MONTHLY-RATE   PIC 9V9(10).
       01  WS-MONTHS         PIC 999.
       01  WS-PAYMENT        PIC 9(7)V99.
       01  ED-MONEY          PIC $$$,$$$,$$9.99.
       PROCEDURE DIVISION.
           COMPUTE WS-MONTHLY-RATE = WS-ANNUAL-RATE / 12
           COMPUTE WS-MONTHS = WS-YEARS * 12
           COMPUTE WS-PAYMENT ROUNDED =
               WS-PRINCIPAL * WS-MONTHLY-RATE
               / (1 - (1 + WS-MONTHLY-RATE) ** (- WS-MONTHS))
               ON SIZE ERROR DISPLAY "Payment overflow"
           END-COMPUTE
           MOVE WS-PAYMENT TO ED-MONEY
           DISPLAY "Monthly payment: " ED-MONEY
           STOP RUN.