MODULE 3 · ARITHMETIC · 3/8

ROUNDED and truncation

12 min30 XPExercise

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.

Check your understanding

1. WS-X is PIC 9V99. What does DIVIDE 3 INTO 2 GIVING WS-X store?
2. WS-R is PIC S9(3)V99. Which value does ROUNDED produce for -2.345?
fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.