MODULE 2 · DATA AND PICTURE · 2/7

PICTURE clauses

15 min30 XPExercise

The PIC (short for PICTURE) clause is a template: one symbol per character position, describing what the field can hold. COBOL fields are fixed length, so the picture also fixes the size.

Symbol Means Example
X any character PIC X(20): 20 characters of text
9 a decimal digit PIC 9(5): a 5-digit number
A a letter or space PIC A(2): two letters
V implied decimal point PIC 9(3)V99: 3 digits, then 2 decimals
S the value can be negative PIC S9(5)V99

A number in brackets repeats the symbol: 9(5) is shorthand for 99999, and 9(3)V99 is 999V99.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PICS.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-PRICE         PIC 9(3)V99   VALUE 12.5.
       01  WS-BALANCE       PIC S9(5)V99  VALUE -250.75.
       01  WS-CODE          PIC X(4)      VALUE "A1-Z".
       01  WS-INITIALS      PIC A(2)      VALUE "JM".
       PROCEDURE DIVISION.
           DISPLAY "PRICE:    " WS-PRICE.
           DISPLAY "BALANCE:  " WS-BALANCE.
           DISPLAY "CODE:     " WS-CODE.
           DISPLAY "INITIALS: " WS-INITIALS.
           DISPLAY "BYTES IN PRICE:   " FUNCTION LENGTH(WS-PRICE).
           DISPLAY "BYTES IN BALANCE: " FUNCTION LENGTH(WS-BALANCE).
           STOP RUN.
PRICE:    012.50
BALANCE:  -00250.75
CODE:     A1-Z
INITIALS: JM
BYTES IN PRICE:   5
BYTES IN BALANCE: 7

V: the decimal point that isn't there

V tells the compiler where the decimal point would be, but no point is stored. WS-PRICE is five bytes holding the digits 01250; the compiler knows the last two are decimals. That is why FUNCTION LENGTH reports 5, not 6.

This is exactly how money arrives in mainframe files: a field such as 0012550 in a record, described by PIC 9(5)V99, means 125.50. Get the picture wrong (say PIC 9(7)) and your program reads it as 12,550, a hundred times too big.

S: the sign

Without S, a numeric field can't be negative. Move a negative value into it and the sign is silently dropped:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SIGNS.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-REFUND        PIC S9(3)     VALUE -42.
       01  WS-NO-SIGN       PIC 9(3).
       PROCEDURE DIVISION.
           MOVE WS-REFUND TO WS-NO-SIGN.
           DISPLAY "SIGNED:   " WS-REFUND.
           DISPLAY "UNSIGNED: " WS-NO-SIGN.
           STOP RUN.
SIGNED:   -042
UNSIGNED: 042

A refund of -42 just became a charge of 42. Any field that can go negative (balances, adjustments, differences) needs S.

Like V, the S takes no extra byte: the sign is stored inside the last digit (this is called an overpunched sign, another punched-card legacy).

GnuCOBOL versus z/OS DISPLAY

GnuCOBOL's DISPLAY helpfully shows 012.50 and -00250.75. On z/OS, DISPLAY writes the raw digits: 01250, and 002507N for the negative balance, where N is the last digit 5 with the sign overpunched on it. For readable output on any platform, use the edited pictures you'll meet later in this module.

X versus 9 versus A

Use 9 only for values you do arithmetic on. Account numbers, phone numbers and postcodes are identifiers, not quantities: declare them X, so leading zeros and letters survive. A is rare in practice; most shops use X for all text.

On the job

When a program produces totals that are exactly 100 times too big or too small, check the V positions in the record layout first.

Your task

A savings account record arrives as one line of 19 characters with no decimal points, exactly as it would sit in a mainframe file:

AC1002S001255000350

The spec for the record is:

Positions Field Content
1–6 IN-ACCT account number, text
7 IN-TYPE account type, one letter
8–14 IN-BAL balance: 5 whole digits, 2 decimals
15–19 IN-RATE interest rate: 1 whole digit, 4 decimals

The program reads the whole record into the group IN-REC with one ACCEPT. Fix the PIC clauses so the fields match the spec. The output for the record above must be:

ACCOUNT: AC1002
TYPE:    S
BALANCE: 00125.50
RATE:    0.0350

Don't change the PROCEDURE DIVISION, and keep each field the same length so the positions still line up.

Check your understanding

1. How many bytes does PIC S9(5)V99 take in the default (DISPLAY) format?
2. A record holds the characters 0012550 in a PIC 9(5)V99 field. What value is that?
3. You MOVE a negative value to a PIC 9(3) field. What happens to the sign?
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.