In COBOL, the type and meaning of data come from the PICTURE clause (and sometimes USAGE). The same logical value can be stored in different internal formats: human-readable (DISPLAY), binary (COMP/COMP-4), or packed decimal (COMP-3). Each format uses a different number of bytes and a different way to store the sign. This page explains how data types and representation work so you can choose the right one for storage, arithmetic, and I/O.
A data type is what kind of value a field holds: numbers, text, or a mix. Representation is how that value is stored in memory. The number 12345 could be stored as five separate digit characters (like on a display), or squeezed into fewer bytes in a special numeric format. COBOL lets you say both "this is a number" (with PICTURE 9) and "store it this way" (with USAGE). Choosing the right representation affects how much space you use and how fast arithmetic is.
The PICTURE (or PIC) clause defines the kind of data and its length. Common symbols are: 9 for a numeric digit, X for any character (alphanumeric), A for alphabetic (letter or space), V for an assumed decimal point (no storage; it only defines where the decimal point is), and S for a sign. The number in parentheses (e.g. 9(5)) gives the count. So PIC 9(5) is five numeric digits; PIC X(20) is 20 characters; PIC S9(7)V99 is a signed number with seven digits before the decimal and two after (the V does not take a byte). Editing symbols (Z, *, $, comma, period, CR, DB) are used for display formatting and change how the value is shown when moved to a display field.
| Symbol | Meaning | Example |
|---|---|---|
| 9 | Numeric digit (0-9) | PIC 9(5) = five digits |
| X | Any character (alphanumeric) | PIC X(10) = 10 characters |
| A | Letter or space | PIC A(20) = letters only |
| V | Assumed decimal point (no storage) | PIC 9(5)V99 = 5 digits, 2 decimal places |
| S | Sign (leading, stored) | PIC S9(4) = signed 4-digit integer |
123401 WS-AMOUNT PIC S9(7)V99. *> Signed, 7 digits + 2 decimals 01 WS-NAME PIC X(30). *> 30 characters 01 WS-CODE PIC 9(5). *> 5 digits, unsigned 01 WS-RATE PIC 9(2)V99. *> 2 integer, 2 decimal (e.g. 0.25)
USAGE (or the shorthand in the PICTURE, like COMP) determines the internal representation. The default is DISPLAY. Other common options are COMP (or COMP-4) for binary, COMP-3 for packed decimal, and COMP-1/COMP-2 for floating-point. The same PICTURE can be stored in different ways; the logical value (e.g. 12345) is the same, but the bytes in memory differ. That affects storage size, arithmetic performance, and how data looks when you move it to a DISPLAY field or a file.
| USAGE | Storage | Typical use |
|---|---|---|
| DISPLAY | 1 byte per character/digit | Default; I/O, display; human-readable |
| COMP / COMP-4 | 2, 4, or 8 bytes (binary) | Integer arithmetic; fast; range by digit count |
| COMP-3 | (n+1)/2 bytes (packed decimal) | Decimal arithmetic; compact; money, quantities |
| COMP-1 / COMP-2 | 4 or 8 bytes (float) | Floating-point; scientific; approximate |
With USAGE DISPLAY, each character or digit occupies one byte. On the mainframe the encoding is usually EBCDIC. The value is human-readable: you can look at the bytes and see the digits or letters. For signed numeric fields (PIC S9...), the sign is stored in the rightmost byte as an "overpunch": the last digit and the sign are combined into one character code (e.g. a special code for "negative 5"). DISPLAY is ideal for data that is read from or written to users or files in character form. Arithmetic on DISPLAY is possible but the runtime must decode and encode each digit; for heavy computation, COMP or COMP-3 is faster.
COMP and COMP-4 are the same: the value is stored in binary (halfword, fullword, or doubleword). The number of digits in the PICTURE determines the size: 1–4 digits use 2 bytes, 5–9 digits use 4 bytes, 10–18 digits use 8 bytes. The sign is in the most significant bit (1 for negative, 0 for positive). Binary arithmetic is fast and is natural for integer math. The range is limited by the size: a 4-byte COMP holds roughly ±2 billion. Be careful with decimal places: COMP does not store a decimal point; if you need exact decimal fractions, use COMP-3 or DISPLAY with a V in the picture.
12301 WS-COUNT PIC S9(4) COMP. *> 2 bytes, -32768 to 32767 01 WS-BIG PIC S9(9) COMP. *> 4 bytes, about ±2 billion 01 WS-ID PIC 9(5) COMP. *> 2 bytes, 0 to 65535 (unsigned)
COMP-3 stores digits in packed form: two decimal digits per byte (each half-byte, or nibble, holds one digit). The rightmost nibble of the last byte holds the sign: hexadecimal C for positive, D for negative. So PIC S9(4) COMP-3 uses (4+1)/2 = 2.5 → 3 bytes (three bytes: two full digits in the first two nibbles of the first two bytes, then the last two digits and the sign in the third byte). PIC S9(5) COMP-3 uses 3 bytes. Packed decimal gives exact decimal arithmetic (no floating-point rounding) and is compact. It is commonly used for money and quantities on the mainframe. When you MOVE a COMP-3 field to a DISPLAY field, the compiler generates code to unpack and format it.
123401 WS-AMT PIC S9(7)V99 COMP-3. *> 5 bytes: 7+2 digits + sign 01 WS-QTY PIC 9(3) COMP-3. *> 2 bytes: 3 digits (unsigned: F in last nibble) *> Value -1234 in S9(4) COMP-3: bytes X'1234D' (hex)
In DISPLAY, the sign is in the rightmost byte, overpunched with the last digit. In COMP/COMP-4, the sign is the high-order bit of the binary value. In COMP-3, the sign is the last nibble (C = positive, D = negative; F is sometimes used for unsigned). When you move data between formats (e.g. COMP-3 to DISPLAY), the compiler and runtime convert the representation so the logical value is preserved. If you REDEFINES a numeric field as alphanumeric and move it, you are moving bytes without conversion; the result is not a readable number.
1. PIC S9(5) COMP-3 uses how many bytes?
2. USAGE DISPLAY is best for:
3. The sign in COMP-3 is stored in: