COBOL Data Division: PIC Clauses, COMP Types, and Level Numbers

The DATA DIVISION is where COBOL programs define all of their data. Unlike languages where variables are scattered throughout the code, COBOL concentrates every data definition in one place before any executable logic begins. This makes COBOL programs highly auditable — a single reading of the DATA DIVISION tells you exactly what the program stores and manipulates.
PIC Clause: The Heart of COBOL Data Definition
The PIC (PICTURE) clause defines the type, size, and format of an elementary data item. Every field that holds actual data has a PIC clause.
Alphanumeric: PIC X
PIC X(n) defines a field of n characters. Any character can be stored — letters, digits, spaces, or special characters:
01 WS-CUSTOMER-NAME PIC X(40).
01 WS-STATUS-CODE PIC XX. *> shorthand for PIC X(2)
01 WS-DESCRIPTION PIC X(100).XX is shorthand for X(2), XXX for X(3), and so on. Beyond 3 characters, use the parenthetical form.
Numeric: PIC 9
PIC 9(n) defines an unsigned decimal integer with n digits:
01 WS-ITEM-COUNT PIC 9(5). *> 0 to 99999
01 WS-YEAR PIC 9999. *> shorthand for 9(4)Signed Numeric: PIC S9
The S prefix makes a numeric field signed. Without S, negative values cannot be stored:
01 WS-TEMPERATURE PIC S9(4). *> -9999 to +9999
01 WS-ADJUSTMENT PIC S9(7)V99. *> signed, 7 integer + 2 decimalDecimal: V
V marks the assumed decimal point. It does not occupy storage — it is a compile-time annotation that tells the compiler where the decimal point is:
01 WS-AMOUNT PIC S9(9)V99. *> -999999999.99 to +999999999.99
01 WS-RATE PIC V9(6). *> .000000 to .999999
01 WS-PRICE PIC 9(7)V99. *> 0000000.00 to 9999999.99For display output, use an edited PIC clause with an actual decimal point:
01 WS-AMOUNT-DISPLAY PIC ZZZ,ZZZ,ZZ9.99-.Alphabetic: PIC A
PIC A(n) accepts only letters and spaces. This is rarely used in modern COBOL; PIC X is preferred because it is more permissive:
01 WS-INITIALS PIC A(3).COMP Storage Types
The storage type determines how a numeric value is physically encoded in memory. Choosing the right type affects both storage efficiency and performance.
Display (Default)
No USAGE clause defaults to USAGE DISPLAY. Each digit occupies one byte in EBCDIC encoding. This is human-readable and useful for report data, but wastes space and is slowest for arithmetic:
01 WS-AGE PIC 9(3). *> 3 bytes, DISPLAYCOMP (COMPUTATIONAL) — Pure Binary
Binary integers. The compiler allocates:
- 2 bytes for PIC 9(1) through 9(4)
- 4 bytes for PIC 9(5) through 9(9)
- 8 bytes for PIC 9(10) through 9(18)
Use COMP for counters, subscripts, loop variables, and any integer that participates in arithmetic but does not need decimal fractions:
01 WS-LOOP-INDEX PIC S9(9) COMP. *> 4 bytes, binary
01 WS-ARRAY-SIZE PIC 9(4) COMP. *> 2 bytes, binary
01 WS-BYTE-COUNT PIC S9(18) COMP. *> 8 bytes, binaryThe S is recommended with COMP even for non-negative values — without it, the compiler may generate additional sign-check instructions on every reference.
COMP-3 (COMPUTATIONAL-3) — Packed Decimal
The most important storage type in financial COBOL. Two digits are packed into each byte, with the rightmost half-byte holding the sign (C for positive, D for negative, F for unsigned):
01 WS-BALANCE PIC S9(11)V99 COMP-3. *> 7 bytes
01 WS-INTEREST-RATE PIC S9(5)V99999 COMP-3. *> 6 bytes
01 WS-TAX-AMOUNT PIC S9(7)V99 COMP-3. *> 5 bytesStorage formula: ceiling((digits + 1) / 2) bytes. So PIC S9(11)V99 has 13 digits, requiring ceiling(14/2) = 7 bytes.
COMP-3 is the standard for financial data because:
- z/Architecture hardware has native packed-decimal arithmetic instructions
- Decimal arithmetic is exact (no floating-point rounding errors)
- Storage is compact — 13-digit field in 7 bytes vs 13 bytes for DISPLAY
COMP-1 and COMP-2 — Floating Point
Single-precision (COMP-1, 4 bytes) and double-precision (COMP-2, 8 bytes) binary floating point. These are occasionally used for scientific calculations but are never appropriate for financial amounts because of inherent floating-point rounding errors:
01 WS-SCIENTIFIC-VALUE PIC +(15)9.999(9) COMP-2.COMP-5 — Native Binary
Like COMP but uses the full word size without z/OS-specific sign conventions. Use when interfacing with C programs or when you need maximum binary performance:
01 WS-C-INT-PARAM PIC S9(9) COMP-5.Level Numbers
Level numbers define the hierarchical (record) structure of data items. They are the backbone of COBOL's record-oriented design.
Levels 01–49: Record Hierarchy
Level 01 is always the top of a record. Items at higher level numbers are subordinate to the nearest lower-numbered item above them:
01 CUSTOMER-RECORD.
05 CR-ACCOUNT-INFO.
10 CR-ACCOUNT-ID PIC X(10).
10 CR-ACCOUNT-TYPE PIC X(2).
05 CR-PERSONAL-INFO.
10 CR-LAST-NAME PIC X(25).
10 CR-FIRST-NAME PIC X(15).
10 CR-DATE-OF-BIRTH.
15 CR-DOB-YEAR PIC 9(4).
15 CR-DOB-MONTH PIC 9(2).
15 CR-DOB-DAY PIC 9(2).
05 CR-BALANCE PIC S9(11)V99 COMP-3.Group items (those with subordinates, like CR-ACCOUNT-INFO) are treated as alphanumeric strings when moved or compared — arithmetic on them causes compiler errors.
Elementary items (those with PIC clauses and no subordinates, like CR-ACCOUNT-ID) are the actual data fields.
Any level number can be used between 02 and 49. Increment by 5 (05, 10, 15...) is conventional — it leaves room to insert intermediate levels without renumbering.
Level 77: Standalone Items
Level 77 is for elementary items that do not belong to a record hierarchy. Functionally equivalent to a level 01 elementary item, but signals that the field stands alone:
77 WS-COUNTER PIC S9(9) COMP VALUE ZERO.
77 WS-FOUND-FLAG PIC X VALUE 'N'.Modern COBOL style prefers using level 01 for standalone items and grouping related items under descriptive group names. Level 77 is valid but increasingly rare in new code.
Level 88: Condition Names
Level 88 entries define named Boolean conditions. They are one of COBOL's most powerful — and underused — features:
01 WS-ACCOUNT-STATUS PIC X(2).
88 ACCT-ACTIVE VALUE 'AC'.
88 ACCT-CLOSED VALUE 'CL'.
88 ACCT-SUSPENDED VALUE 'SU'.
88 ACCT-PENDING VALUE 'PE'.
01 WS-EOF-FLAG PIC X VALUE 'N'.
88 AT-END-OF-FILE VALUE 'Y'.
88 MORE-RECORDS VALUE 'N'.You SET a condition name to TRUE to assign the value:
SET ACCT-ACTIVE TO TRUE *> moves 'AC' to WS-ACCOUNT-STATUS
SET AT-END-OF-FILE TO TRUE *> moves 'Y' to WS-EOF-FLAGYou test condition names directly:
IF ACCT-ACTIVE
PERFORM PROCESS-ACTIVE-ACCOUNT
ELSE IF ACCT-CLOSED
PERFORM ARCHIVE-ACCOUNT
END-IF
PERFORM UNTIL AT-END-OF-FILE
PERFORM PROCESS-RECORD
PERFORM READ-NEXT-RECORD
END-PERFORM88-level conditions eliminate magic literals scattered through the PROCEDURE DIVISION. They also make the code self-documenting and reduce the risk of typos in status comparisons.
Level 66: RENAMES
Level 66 creates an alternative view of a group of consecutive fields:
01 DATE-FIELDS.
05 DF-YEAR PIC 9(4).
05 DF-MONTH PIC 9(2).
05 DF-DAY PIC 9(2).
66 DATE-AS-STRING RENAMES DF-YEAR THRU DF-DAY.DATE-AS-STRING now refers to all 8 bytes of the three date fields as a single alphanumeric string. RENAMES is rarely used in modern code; REDEFINES (covered next) is more flexible.
REDEFINES
REDEFINES lets two or more data names occupy the same storage area, providing different interpretations of the same bytes:
01 WS-PACKED-DATE PIC 9(8).
01 WS-STRUCTURED-DATE REDEFINES WS-PACKED-DATE.
05 WSD-YEAR PIC 9(4).
05 WSD-MONTH PIC 9(2).
05 WSD-DAY PIC 9(2).01 WS-UNION.
05 WS-NUMERIC-VALUE PIC S9(9) COMP-3.
05 WS-CHAR-VALUE REDEFINES WS-NUMERIC-VALUE PIC X(5).Rules for REDEFINES:
- The redefining item must immediately follow the redefined item at the same level
- The redefining item cannot be longer than the redefined item
- VALUE clauses are not allowed on redefining items (except for 88-levels)
- Do not REDEFINES a REDEFINES directly — create a chain through the original
FILLER
FILLER is a data-name placeholder for fields you never need to reference by name:
01 REPORT-HEADER.
05 FILLER PIC X(20) VALUE 'CUSTOMER BALANCE REPORT'.
05 FILLER PIC X(5) VALUE SPACES.
05 RH-DATE PIC X(10).
05 FILLER PIC X(105) VALUE SPACES.
01 ACCOUNT-RECORD-LAYOUT.
05 AR-ACCOUNT-ID PIC X(10).
05 AR-BALANCE PIC S9(11)V99 COMP-3.
05 FILLER PIC X(81). *> reserved / padding to 100 bytesMultiple FILLER fields in the same record are allowed — each is independent. In IBM Enterprise COBOL, you can also simply omit the data-name entirely, which is equivalent to coding FILLER:
01 REPORT-HEADER.
05 PIC X(20) VALUE 'CUSTOMER BALANCE REPORT'.
05 RH-DATE PIC X(10).
05 PIC X(105) VALUE SPACES.VALUE Clause
The VALUE clause sets the initial value of a WORKING-STORAGE item. It is only valid in WORKING-STORAGE and LOCAL-STORAGE sections (not in FILE SECTION records):
01 WS-CONSTANTS.
05 WS-MAX-RETRIES PIC 9(2) COMP VALUE 3.
05 WS-DEFAULT-STATUS PIC X(2) VALUE 'AC'.
05 WS-ZERO-AMOUNT PIC S9(9)V99 COMP-3 VALUE ZERO.
05 WS-SPACES PIC X(80) VALUE SPACES.Special figurative constants for VALUE:
ZERO/ZEROS/ZEROES— numeric or alphanumeric zerosSPACE/SPACES— blank charactersHIGH-VALUE/HIGH-VALUES— highest collating sequence character (X'FF')LOW-VALUE/LOW-VALUES— lowest collating sequence character (X'00')NULL/NULLS— null pointer for USAGE POINTER items
Designing Efficient Data Layouts
For COMP fields, align them to their natural boundaries to avoid double-word fetches on z/Architecture:
01 WS-ALIGNED-RECORD.
05 WS-8BYTE-COMP PIC S9(18) COMP. *> align on 8-byte boundary
05 WS-4BYTE-COMP PIC S9(9) COMP. *> align on 4-byte boundary
05 WS-4BYTE-COMP2 PIC S9(9) COMP. *> fill to 8-byte boundary
05 WS-2BYTE-COMP PIC S9(4) COMP. *> align on 2-byte boundary
05 FILLER PIC XX. *> pad to 4-byte boundary
05 WS-CHAR-FIELD PIC X(20). *> then alphanumericThe IBM Enterprise COBOL TRUNC(BIN) compile option aligns binary fields automatically. Check your installation standards for the recommended compiler options.
Next Steps
Understanding PIC clauses and level numbers gives you the vocabulary to read any COBOL DATA DIVISION. The next step is mastering WORKING-STORAGE patterns — how to organize flags, counters, and communication areas effectively. See the COBOL Working Storage guide, or return to the full curriculum at COBOL Mastery.
