A payroll program may read gross pay, then subtract tax, insurance, and loan recovery before writing net pay. In COBOL, the SUBTRACT statement handles that pattern directly. The important choice is whether the original amount should be changed, or whether the result should be written to a separate field with GIVING.
What is the COBOL SUBTRACT statement?
The SUBTRACT statement subtracts one numeric item, or the sum of several numeric items, from another numeric item and stores the result. IBM documents three main forms: basic SUBTRACT ... FROM, SUBTRACT ... FROM ... GIVING, and SUBTRACT CORRESPONDING.
The statement is easy to read when the business rule is a simple reduction. For a longer formula, COMPUTE may be clearer because the full expression appears on one side of the equals sign.
Basic SUBTRACT FROM format
Use the basic form when the value after FROM should be reduced in place. The receiving field is changed immediately.
SUBTRACT amount-1 [amount-2 ...] FROM result-field
[ROUNDED]
[ON SIZE ERROR imperative-statement]
END-SUBTRACT
Example: reduce a counter
01 WS-RETRY-COUNT PIC 9(02) VALUE 03.
SUBTRACT 1 FROM WS-RETRY-COUNT
END-SUBTRACT.
After the statement runs, WS-RETRY-COUNT contains 02. This form is common in loops, retry logic, and balance calculations where the field itself should hold the new value.
SUBTRACT FROM GIVING format
Use GIVING when the source value must remain unchanged. COBOL subtracts the amount before FROM from the value after FROM, then places the answer in the field after GIVING.
SUBTRACT amount-1 [amount-2 ...]
FROM source-value
GIVING result-field
[ROUNDED]
[ON SIZE ERROR imperative-statement]
END-SUBTRACT
Example: calculate net pay
01 WS-GROSS-PAY PIC S9(7)V99 COMP-3.
01 WS-TAX-AMOUNT PIC S9(5)V99 COMP-3.
01 WS-INSURANCE-AMOUNT PIC S9(5)V99 COMP-3.
01 WS-NET-PAY PIC S9(7)V99 COMP-3.
SUBTRACT WS-TAX-AMOUNT WS-INSURANCE-AMOUNT
FROM WS-GROSS-PAY
GIVING WS-NET-PAY
END-SUBTRACT.
If gross pay is 2500.00, tax is 420.00, and insurance is 80.00, the result is 2000.00. WS-GROSS-PAY is still 2500.00 because the statement used GIVING.
SUBTRACT CORRESPONDING format
SUBTRACT CORRESPONDING, often written as SUBTRACT CORR, works with group items. COBOL matches elementary items by name and subtracts matching numeric fields. This can be useful, but many teams avoid it in business code because the result depends on matching data names inside both groups.
01 WS-OLD-TOTALS.
05 WS-COUNT PIC 9(05).
05 WS-AMOUNT PIC S9(7)V99 COMP-3.
01 WS-ADJUSTMENT-TOTALS.
05 WS-COUNT PIC 9(05).
05 WS-AMOUNT PIC S9(7)V99 COMP-3.
SUBTRACT CORRESPONDING WS-ADJUSTMENT-TOTALS
FROM WS-OLD-TOTALS
END-SUBTRACT.
Review group layouts carefully before using this form. A field name change, copybook change, or added elementary item can change what gets subtracted.
ROUNDED and ON SIZE ERROR
Add ROUNDED when the receiving field has fewer decimal places than the calculated result and the business rule expects rounding. IBM notes that rounding is done before size-error checking.
01 WS-DISCOUNT PIC S9(5)V999 COMP-3.
01 WS-INVOICE-AMOUNT PIC S9(7)V99 COMP-3.
01 WS-AFTER-DISCOUNT PIC S9(7)V99 COMP-3.
01 WS-CALC-STATUS PIC X(20).
SUBTRACT WS-DISCOUNT
FROM WS-INVOICE-AMOUNT
GIVING WS-AFTER-DISCOUNT ROUNDED
ON SIZE ERROR
MOVE 'SUBTRACT OVERFLOW' TO WS-CALC-STATUS
NOT ON SIZE ERROR
MOVE 'SUBTRACT OK' TO WS-CALC-STATUS
END-SUBTRACT.
A size error can occur when the result cannot fit in the receiving field after decimal alignment. When ON SIZE ERROR is coded and a size error occurs, the affected result field is not changed. That behavior matters in production programs because an old value can remain in the field unless the error path handles it clearly.
SUBTRACT vs COMPUTE
| Use case | Better statement | Reason |
|---|---|---|
| Reduce one counter or balance | SUBTRACT |
Short and direct. |
| Keep the source amount unchanged | SUBTRACT ... GIVING |
The result goes to a separate field. |
| Calculate a formula with several operators | COMPUTE |
The full arithmetic expression is easier to inspect. |
| Subtract same-named fields in two groups | SUBTRACT CORRESPONDING |
Works only when the group layouts are intentionally matched. |
Common mistakes
Changing the source field by accident
SUBTRACT WS-TAX FROM WS-GROSS-PAY changes WS-GROSS-PAY. If later logic still needs the original gross amount, use GIVING.
Using a receiving field that is too small
A result field such as PIC S9(3)V99 cannot hold a large payroll amount. Define enough digits and code ON SIZE ERROR when bad input or a large adjustment should be trapped.
Skipping END-SUBTRACT in nested code
END-SUBTRACT makes the statement boundary clear. It is especially useful when SUBTRACT has ON SIZE ERROR logic inside an IF or EVALUATE.
Quick checklist
- Use
SUBTRACT ... FROMonly when theFROMfield should be updated. - Use
GIVINGwhen the original value must be preserved. - Use
ROUNDEDwhen decimal rounding is part of the rule. - Use
ON SIZE ERRORfor payroll, billing, balance, and adjustment calculations where overflow should not pass silently. - Prefer
COMPUTEfor mixed arithmetic expressions.
Related COBOL arithmetic topics
For connected examples, read COBOL COMPUTE Statement, COBOL DIVIDE Clause, COBOL MULTIPLY Statement, COBOL USAGE Clause, COBOL ARITH Compiler Option, and COBOL Decision Making.
External references
Technical behavior in this refresh was checked against IBM Enterprise COBOL SUBTRACT statement documentation and IBM size error phrase documentation.
FAQ
Does COBOL SUBTRACT change the FROM field?
Yes, the basic SUBTRACT ... FROM form stores the result back in the FROM field. Use GIVING if the original value must stay unchanged.
Can COBOL SUBTRACT handle more than one amount?
Yes. COBOL adds the amounts before FROM and subtracts that total from the value after FROM.
When should I use ON SIZE ERROR?
Use it when the result may not fit in the receiving field, especially in money, balance, quantity, or adjustment calculations.
Should I use SUBTRACT or COMPUTE?
Use SUBTRACT for a simple reduction. Use COMPUTE when the formula mixes several arithmetic operations.
No comments:
Post a Comment