PICTURE clauses and how data is stored
The PIC clause says what a field holds and how big it is. The USAGE says how it is physically stored. Getting these wrong is the single largest source of COBOL run-time failures.
Reading a PICTURE
| PIC | Means | Example value |
|---|---|---|
| PIC X(10) | 10 characters, anything | 'SMITH ' |
| PIC 9(5) | 5 digits, unsigned | 00042 |
| PIC S9(5) | 5 digits, signed | -00042 |
| PIC S9(7)V99 | 7 digits, an implied decimal point, 2 decimals | 0001234.56 |
| PIC A(20) | Letters and spaces only | rarely used |
| PIC 9(3)V9(2) | Same as S9(3)V99 without the sign | |
| PIC ZZZ,ZZ9.99- | An edited field for printing | ' 12,345.67-' |
USAGE: how it is physically stored
| USAGE | Also called | Storage | Use for |
|---|---|---|---|
| DISPLAY | the default | One byte per digit or character | Anything read or written as text |
| COMP-3 | packed decimal | Two digits per byte, sign in the last nibble | Money and counters — the workhorse |
| COMP / BINARY | binary | 2, 4 or 8 bytes | Subscripts, counters, flags |
| COMP-1 / COMP-2 | floating point | 4 / 8 bytes | Scientific work; almost never money |
Why COMP-3 is everywhere
Packed decimal stores two digits per byte and keeps exact decimal arithmetic. A PIC S9(7)V99 COMP-3 field holds nine digits in five bytes, computes money exactly, and is the format the hardware has instructions for. It is the default choice for any numeric business field. The cost is that you cannot read it in a dump without decoding it — which is exactly the skill the next lesson needs.
MOVE and the rules that surprise people
* character move: left-justified, padded or truncated on the RIGHT 01 WS-A PIC X(05) VALUE 'ABCDE'. 01 WS-B PIC X(03). MOVE WS-A TO WS-B >> WS-B = 'ABC' (E and D lost) * numeric move: aligned on the DECIMAL POINT, padded or truncated at both ends 01 WS-C PIC S9(5)V99 VALUE 12345.67. 01 WS-D PIC S9(3)V9. MOVE WS-C TO WS-D >> WS-D = 345.6 (high-order AND low-order lost) * the silent one that causes S0C7 later 01 WS-E PIC X(05) VALUE SPACES. 01 WS-F PIC 9(05). MOVE WS-E TO WS-F >> WS-F now contains spaces, not digits ADD 1 TO WS-F >> S0C7
Initialising properly
INITIALIZEsets numeric fields to zero and character fields to spaces, following the field types.MOVE ZEROES TOa group item moves the *character* zero to every byte — which is not the same as setting a COMP-3 field to zero.VALUEclauses in WORKING-STORAGE initialise once at program start, not on every call in a subprogram.
Example, line by line
01 CUSTOMER-RECORD. 05 CUSTOMER-ID PIC 9(8). 05 CUSTOMER-NAME PIC X(40). 05 BALANCE PIC S9(7)V99 COMP-3. 05 STATUS-CODE PIC X. 88 ACTIVE VALUE 'A'.Try it yourself
How many bytes does BALANCE, defined as PIC S9(7)V99 COMP-3, occupy?
Show a hint
Packed decimal stores two digits per byte, and the sign needs half a byte.
Show the solution
5 bytes. 9 digits plus the sign is 10 half-bytes, and two half-bytes fit in each byte.
Common mistakes
Groups are character data. If it contains spaces or packed data, the target is now invalid and the next arithmetic abends S0C7.
Overflow truncates silently. Add ON SIZE ERROR on any calculation where the result could exceed the field.
REDEFINES reinterprets the same bytes; it does not convert anything. Reading a character field through a numeric REDEFINES gives you garbage.
Binary is fine for subscripts and counts. Money should be COMP-3 so decimal arithmetic stays exact.
What you will see at work
- Copybooks define these layouts once and are shared. Changing a field length means recompiling every program that uses the copybook — a genuine project, not a small edit.
- Records arriving from other platforms often need conversion; a packed field written by a distributed system is a frequent source of bad data.
- When a field 'looks empty' in a browse, it may be COMP-3 and simply unreadable as text. Use a hex display (HEX ON in the editor) to see it.
Key terms
Check your understanding.
Take this lesson's quiz and save your progress. Free.