USAGE: DISPLAY, COMP and COMP-3
So far every number you've declared was stored as text: PIC 9(5)
holds five characters, one digit each. That's USAGE DISPLAY, the default.
COBOL lets you choose other storage formats with the USAGE clause (the
word USAGE itself is optional):
IDENTIFICATION DIVISION.
PROGRAM-ID. USAGES.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-ZONED PIC S9(7)V99 VALUE -1234.56.
01 WS-BINARY PIC S9(7)V99 COMP VALUE -1234.56.
01 WS-PACKED PIC S9(7)V99 COMP-3 VALUE -1234.56.
01 WS-COUNT PIC S9(4) COMP VALUE 25.
PROCEDURE DIVISION.
DISPLAY "ZONED: " WS-ZONED " BYTES "
FUNCTION LENGTH(WS-ZONED)
DISPLAY "BINARY: " WS-BINARY " BYTES "
FUNCTION LENGTH(WS-BINARY)
DISPLAY "PACKED: " WS-PACKED " BYTES "
FUNCTION LENGTH(WS-PACKED)
DISPLAY "COUNT: " WS-COUNT " BYTES "
FUNCTION LENGTH(WS-COUNT)
ADD WS-PACKED TO WS-ZONED
DISPLAY "MIXED: " WS-ZONED
STOP RUN.
Output:
ZONED: -0001234.56 BYTES 9
BINARY: -0001234.56 BYTES 4
PACKED: -0001234.56 BYTES 5
COUNT: +0025 BYTES 2
MIXED: -0002469.12
Same value, three sizes. DISPLAY converts each back to readable digits,
and arithmetic across usages just works — the compiler inserts the
conversions. What changes is how many bytes the field uses and how fast the
arithmetic is.
DISPLAY (zoned decimal)
One byte per digit. The sign is folded into the last byte (that's why it's
called zoned). Easy to read in a file dump, but the CPU can't calculate
with it directly: every ADD first converts to another format and back.
Use it for data that's printed or exchanged as text.
COMP (binary)
COMP (also BINARY or COMP-4) stores a binary integer — 2 bytes for 1–4
digits, 4 bytes for 5–9, 8 bytes for 10–18. Implied decimals still work: the
compiler just remembers where the V is. Binary is ideal for counters,
subscripts and lengths, and it's what other languages and system APIs
expect. The size limits come from the picture, not the bytes: a
PIC S9(4) COMP field holds ±9999 even though a halfword could hold more
(add 1 to 9999 in GnuCOBOL and you get 0; on z/OS the TRUNC compiler
option decides).
COMP-3 (packed decimal)
COMP-3 (also PACKED-DECIMAL) stores two digits per byte, with the
sign in the last half-byte. Nine digits plus sign = ten half-bytes = 5
bytes. The formula: (digits + 1) / 2, rounded up.
Why does packed decimal exist? Because IBM mainframes have decimal
arithmetic in hardware. Instructions such as AP (add packed) and MP
(multiply packed) work directly on packed fields, exactly, in base 10. There
is no binary conversion, so 0.10 is exactly 0.10 — no floating-point
surprises like 0.1 + 0.2 = 0.30000000000000004. That's why money fields in
bank, insurance and payroll files are almost always PIC S9(n)V99 COMP-3.
They're also nearly half the size of zoned fields, which mattered when disk
was expensive and still matters when a file has 200 million records.
Never use COMP-1 or COMP-2 for money
COMP-1 and COMP-2 are floating-point (like float and double).
They're approximate. You'll rarely see them in business code, and a
reviewer will reject them for currency.
Coming later
A later module looks at these formats byte by byte in hex — what
X'0123456D' means, and why a S0C7 data exception happens when a
packed field holds garbage.
On the job
When you see a copybook, the USAGE tells you the file's physical
layout. Get it wrong — say, declare a COMP-3 amount as DISPLAY —
and every field after it is read from the wrong position. Record
lengths in JCL and file definitions are calculated from these byte
counts, so learn the formulas.