ROUNDED and truncation
You saw in the last lesson that COBOL truncates extra decimal places. For
money that's usually wrong: a tax authority expects 4.5977 to be charged as
4.60, not 4.59. Add the word ROUNDED after the receiving field and COBOL
rounds instead:
IDENTIFICATION DIVISION.
PROGRAM-ID. ROUNDING.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-NET PIC 9(5)V99 VALUE 19.99.
01 WS-RATE PIC V99 VALUE .23.
01 WS-VAT-CUT PIC 9(5)V99.
01 WS-VAT-RND PIC 9(5)V99.
01 WS-CREDIT PIC S9(3)V999 VALUE -2.345.
01 WS-RESULT PIC S9(3)V99.
PROCEDURE DIVISION.
MULTIPLY WS-NET BY WS-RATE GIVING WS-VAT-CUT
MULTIPLY WS-NET BY WS-RATE GIVING WS-VAT-RND ROUNDED
DISPLAY "TRUNCATED: " WS-VAT-CUT
DISPLAY "ROUNDED: " WS-VAT-RND
ADD 0 TO WS-CREDIT GIVING WS-RESULT ROUNDED
DISPLAY "NEGATIVE: " WS-RESULT
STOP RUN.
Output:
TRUNCATED: 00004.59
ROUNDED: 00004.60
NEGATIVE: -002.35
19.99 × 0.23 = 4.5977. Truncated, that's 4.59; rounded, 4.60.
How ROUNDED rounds
Default ROUNDED looks at the first digit that doesn't fit. If it is 5 or
more, the last kept digit goes up by one — away from zero for negative
numbers, so -2.345 becomes -2.35, not -2.34.
ROUNDED belongs to the receiving field, so it goes right after it:
GIVING WS-VAT ROUNDED, ADD A TO B ROUNDED. With several receivers you
choose per field: ADD 1.555 TO WS-X ROUNDED WS-Y rounds WS-X only.
Other rounding modes
The 2002 standard added ROUNDED MODE, for example
ROUNDED MODE NEAREST-EVEN (banker's rounding, where 2.345 goes to
2.34). GnuCOBOL supports it, but many shops' compilers and standards
don't, so plain ROUNDED is what you'll see in existing code.
Round once, at the end
A multi-step calculation should keep full precision in the intermediate fields and round only the final result. Round every step and the errors accumulate — a few cents per record adds up to real money over a ten-million-record batch run. The usual pattern:
01 WS-WORK PIC 9(9)V9(4).
MULTIPLY WS-NET BY WS-RATE-PCT GIVING WS-WORK
DIVIDE WS-WORK BY 100 GIVING WS-VAT ROUNDED
WS-WORK has four decimals — enough to hold the product of two
two-decimal fields exactly — and only the last step rounds to cents.
On the job
Which rounding rule to apply is a business decision, often written
into the spec ("round half up at line level, not invoice level").
When you change a calculation, check where the old code rounded: moving
ROUNDED from one statement to another can change totals by a cent,
and auditors notice.
Your task
Read an invoice line's net amount (e.g. 19.99) and a VAT rate in
percent (e.g. 23 or 13.5), one per line.
VAT = net × rate ÷ 100. Show it truncated and rounded to the cent, then the gross amount (net + rounded VAT):
VAT TRUNCATED: 4.59
VAT ROUNDED: 4.60
GROSS: 24.59
Keep full precision in WS-WORK and apply ROUNDED only on the final
division. Use the verbs (MULTIPLY, DIVIDE, ADD), not COMPUTE.
The display lines are already written for you.