ADD and SUBTRACT
COBOL was designed so a business analyst could read the arithmetic. Instead
of balance = balance + deposit you write a sentence:
ADD WS-DEPOSIT TO WS-BALANCE
That statement changes WS-BALANCE: the value of WS-DEPOSIT is added
to it and the result replaces what was there. The field after TO is both an
input and the receiving field.
The TO form
You can add several values at once, and even into several receivers:
IDENTIFICATION DIVISION.
PROGRAM-ID. ADDTO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-A PIC 9(3) VALUE 10.
01 WS-B PIC 9(3) VALUE 20.
01 WS-C PIC 9(3) VALUE 5.
PROCEDURE DIVISION.
ADD WS-A TO WS-B
DISPLAY WS-A " " WS-B
ADD WS-A WS-C TO WS-B
DISPLAY WS-B
ADD 1 TO WS-B WS-C
DISPLAY WS-B " " WS-C
STOP RUN.
Output:
010 030
045
046 006
ADD WS-A WS-C TO WS-B adds both values to WS-B. ADD 1 TO WS-B WS-C
adds 1 to each receiver. The sending fields (WS-A) never change.
The GIVING form
When you want to keep the inputs untouched, use GIVING. The result goes
only into the field after GIVING, and whatever was there before is
replaced:
ADD WS-OPENING WS-DEPOSIT GIVING WS-TOTAL-IN
You will also meet ADD WS-A TO WS-B GIVING WS-C. With GIVING, the TO
is just noise: WS-B is not changed, only WS-C receives the sum. Read
GIVING as "the answer goes here and nowhere else".
SUBTRACT ... FROM
SUBTRACT mirrors ADD. Everything before FROM is summed, then taken
away from the field after FROM:
SUBTRACT WS-FEE WS-WITHDRAWAL FROM WS-BALANCE
SUBTRACT WS-DISCOUNT FROM WS-PRICE GIVING WS-NET
The second form leaves WS-PRICE alone and puts the difference in WS-NET.
Unsigned fields lose the sign
If the receiving field has no S in its picture, a negative result is
stored without its sign. With WS-A PIC 9(3) VALUE 10,
SUBTRACT 50 FROM WS-A leaves 040, not -040. Any field that could go
negative (balances, adjustments, variances) must be PIC S9....
Decimal alignment is automatic
Fields with different numbers of implied decimals (V) line up correctly:
adding a PIC 9(3)V99 to a PIC 9(5)V9(4) works on the decimal point, just
as you would on paper. You never shift values by hand.
On the job
In batch programs you will see long runs of ADD WS-TXN-AMT TO
WS-DAILY-TOTAL style statements accumulating totals for reports.
Reviewers like them because they are unambiguous: exactly one field
changes, and it's named right there.
Your task
A teller program reads three amounts, one per line: the opening
balance, a deposit and a withdrawal, typed with a decimal point.
The input fields are declared PIC 9(7)V99 — wider than the values need,
because GnuCOBOL's ACCEPT reads only as many characters as the field has
digit positions.
- Use
ADD ... GIVINGto put opening balance + deposit intoWS-BALANCE. - Use
SUBTRACT ... FROMto take the withdrawal offWS-BALANCE. - Display the balance through the edited field that is already declared.
For input 1000.00, 250.50, 100.25 the output is:
CLOSING BALANCE: 1,150.25
Don't use COMPUTE — that comes later in this module.