COBOLMainframe

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

TT
TopicTrick
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:

cobol
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:

cobol
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:

cobol
01 WS-TEMPERATURE       PIC S9(4).       *> -9999 to +9999
01 WS-ADJUSTMENT        PIC S9(7)V99.    *> signed, 7 integer + 2 decimal

Decimal: 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:

cobol
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.99

For display output, use an edited PIC clause with an actual decimal point:

cobol
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:

cobol
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:

cobol
01 WS-AGE               PIC 9(3).        *> 3 bytes, DISPLAY

COMP (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:

cobol
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, binary

The 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):

cobol
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 bytes

Storage 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:

cobol
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:

cobol
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:

cobol
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:

cobol
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:

cobol
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:

cobol
SET ACCT-ACTIVE TO TRUE          *> moves 'AC' to WS-ACCOUNT-STATUS
SET AT-END-OF-FILE TO TRUE       *> moves 'Y' to WS-EOF-FLAG

You test condition names directly:

cobol
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-PERFORM

88-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:

cobol
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:

cobol
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).
cobol
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:

cobol
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 bytes

Multiple 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:

cobol
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):

cobol
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 zeros
  • SPACE / SPACES — blank characters
  • HIGH-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:

cobol
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 alphanumeric

The 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.