Formatting Numbers for Humans

COBOL GnuCOBOL 3.2.0 ยท โœ“ verified by execution on 2026-08-16

In modern languages, if you have a number like 1500 and want to print it as $1,500.00, you call a formatting function (like formatMoney() or Intl.NumberFormat).

A reasonable person coming to COBOL expects a similar utility function. But this intuition fails because COBOL was designed in an era where CPU cycles were precious. Calling a runtime formatting function repeatedly for every line in a massive payroll report would waste expensive processing time.

To solve this, COBOL designers made formatting a structural, declarative operation rather than a runtime function call. The format is literally baked into how the memory is defined. When you MOVE data into this specially structured memory space, the CPU formats the data at the byte level during the transfer. This is called an edited PICTURE clause.

Insertion Symbols

The most basic editing is inserting characters like commas and decimal points.

Predict the output cobol

Read the code. What exactly will it print? Commit to an answer before you look.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. EDIT-DEMO.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 RAW-NUM PIC 9(4) VALUE 1000.
       01 EDITED-NUM PIC 9,999.
       PROCEDURE DIVISION.
           MOVE RAW-NUM TO EDITED-NUM.
           DISPLAY EDITED-NUM.
           STOP RUN.
Output
1,000

Notice the difference between an assumed decimal point (V) and a physical decimal point (.):

cobol โœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. DEC-INSERT.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 RAW-DEC PIC 99V99 VALUE 15.50.
       01 EDITED-DEC PIC 99.99.
       PROCEDURE DIVISION.
           MOVE RAW-DEC TO EDITED-DEC.
           DISPLAY EDITED-DEC.
           STOP RUN.
Output
15.50

V aligns math but takes up no memory space. . takes up a physical byte in memory and is used purely for display.

Zero Suppression (Z)

If you have a 5-digit variable holding the number 42, COBOL will normally print 00042. To replace those leading zeros with spaces, use the Z symbol.

Source (PIC 9(5)) 0 0 0 4 2 Destination (PIC ZZZZ9) _ _ _ 4 2 Leading zeros are replaced by spaces.
cobol โœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ZERO-SUPP.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 RAW-VAL PIC 9(5) VALUE 42.
       01 DISP-VAL PIC ZZZZ9.
       PROCEDURE DIVISION.
           MOVE RAW-VAL TO DISP-VAL.
           DISPLAY '[' DISP-VAL ']'.
           STOP RUN.
Output
[   42]

Why ZZZZ9 instead of ZZZZZ? If the value was exactly 0, ZZZZZ would suppress every digit, leaving a completely blank field:

cobol โœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. BLANK-ZERO.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 ZERO-VAL PIC 9 VALUE 0.
       01 ALL-Z PIC ZZZZ.
       PROCEDURE DIVISION.
           MOVE ZERO-VAL TO ALL-Z.
           DISPLAY '[' ALL-Z ']'.
           STOP RUN.
Output
[    ]

Floating Currency ($$)

To print monetary amounts, you can use a floating $. By using multiple $ symbols, COBOL acts as a zero-suppressor and prints a single $ immediately to the left of the first non-zero digit.

Source (PIC 9(5)) 0 1 5 0 0 Destination (PIC $$,$$9) _ $1 , 5 0 0 The '$' floats to the first significant digit.
cobol โœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. FLOAT-CURR.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 RAW-MONEY PIC 9(5) VALUE 1500.
       01 DISP-MONEY PIC $$,$$9.
       PROCEDURE DIVISION.
           MOVE RAW-MONEY TO DISP-MONEY.
           DISPLAY DISP-MONEY.
           STOP RUN.
Output
$1,500

The Boundary: No Math on Display Fields

A common intuition is that you can calculate directly on these formatted fields (e.g., ADD 10 TO DISP-MONEY), because they represent numeric concepts. You cannot.

This is the hard boundary where the rule of edited clauses stops: they are strictly for printing and display. Once a number is moved into an edited picture clause, it belongs to the alphanumeric or numeric-edited category. It is effectively a string of ASCII characters (like $, ,, and spaces) meant for human eyes, not for computational storage.

Attempting math on an edited field is a syntax error.

cobol โœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. DE-EDIT.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 RAW-NUM PIC 9(3) VALUE 50.
       01 EDITED-NUM PIC ZZZ9.
       PROCEDURE DIVISION.
           MOVE RAW-NUM TO EDITED-NUM.
      *>   ADD 10 TO EDITED-NUM is illegal.
      *>   We must compute on RAW-NUM, then format it.
           ADD 10 TO RAW-NUM.
           MOVE RAW-NUM TO EDITED-NUM.
           DISPLAY '[' EDITED-NUM ']'.
           STOP RUN.
Output
[  60]

Try it yourself

Check yourself

Which PIC clause symbol replaces leading zeros with spaces?

Reveal answer

Z โ€” The Z symbol is used for zero suppression.

What happens if you try to perform arithmetic on an edited numeric field?

Reveal answer

It results in a syntax error or garbage data. โ€” Once formatted, an edited field acts like a string for display only. You cannot do math on it.

What is the difference between an assumed decimal ('V') and an inserted decimal ('.')?

Reveal answer

'V' is for math alignment and takes no space, '.' takes a byte for display. โ€” An assumed decimal ('V') tells the compiler where the decimal point is for math, without taking up a physical byte. A literal decimal ('.') is inserted for display and takes up a character position.

Challenges

Challenge 1 +20 XP

This report prints '000005'. Change the DISPLAY-SCORE variable's PIC clause to use zero suppression so it prints ' 5' instead.

cobol โœ“ solution verified at build time

COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the fixed code should be, then open the solution and compare. The expected output below is real โ€” it came from compiling the solution with GnuCOBOL when this page was built.

  • Test 1 โ€” expects "[ 5]\n"
Need a hint? (โˆ’25% XP)

Change 'PIC 9(6)' to 'PIC ZZZZZ9'.

Show solution (0 XP)
IDENTIFICATION DIVISION.
PROGRAM-ID. FIX-ZEROS.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 RAW-SCORE PIC 9(6) VALUE 5.
01 DISPLAY-SCORE PIC ZZZZZ9.
PROCEDURE DIVISION.
    MOVE RAW-SCORE TO DISPLAY-SCORE.
    DISPLAY '[' DISPLAY-SCORE ']'.
    STOP RUN.

Challenge 2 +20 XP

Format the raw salary to look like a paycheck using a floating currency symbol and a comma. Change the PIC clause to '$$$,$$9'.

cobol โœ“ solution verified at build time

COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the fixed code should be, then open the solution and compare. The expected output below is real โ€” it came from compiling the solution with GnuCOBOL when this page was built.

  • Test 1 โ€” expects "$45,000\n"
Need a hint? (โˆ’25% XP)

Use 'PIC $$$,$$9'.

Show solution (0 XP)
IDENTIFICATION DIVISION.
PROGRAM-ID. PAYCHECK.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 RAW-SALARY PIC 9(6) VALUE 45000.
01 PRINT-SALARY PIC $$$,$$9.
PROCEDURE DIVISION.
    MOVE RAW-SALARY TO PRINT-SALARY.
    DISPLAY PRINT-SALARY.
    STOP RUN.