MODULE 13 · MAINFRAME INTERNALS AND CAPSTONE · 4/10

COMP, BINARY and SYNC

12 min10 XPQuiz

COMP (also BINARY, COMP-4) stores a two's-complement binary integer, the same format C, Java and the z/Architecture CPU use for int. Sizes follow the digit count:

Digits Bytes Mainframe name
1–4 2 halfword
5–9 4 fullword
10–18 8 doubleword

z/OS is big-endian: the most significant byte comes first, so the hex reads naturally. GnuCOBOL writes COMP big-endian too, which is why the bytes below match what you'd see on the mainframe.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. BINARY1.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-HALF      PIC S9(4) COMP   VALUE +300.
       01  WS-NEG       PIC S9(4) COMP   VALUE -1.
       01  WS-FULL      PIC S9(9) COMP   VALUE +100000.
       01  WS-STD       PIC S9(4) COMP   VALUE 9999.
       01  WS-NATIVE    PIC S9(4) COMP-5 VALUE 9999.
       01  WS-PLAIN.
           05  P-FLAG   PIC X.
           05  P-COUNT  PIC S9(9) COMP.
           05  P-CODE   PIC X.
           05  P-LEN    PIC S9(4) COMP.
       01  WS-ALIGNED.
           05  A-FLAG   PIC X.
           05  A-COUNT  PIC S9(9) COMP SYNC.
           05  A-CODE   PIC X.
           05  A-LEN    PIC S9(4) COMP SYNC.
       PROCEDURE DIVISION.
           DISPLAY "+300    X'" FUNCTION HEX-OF(WS-HALF) "'"
           DISPLAY "-1      X'" FUNCTION HEX-OF(WS-NEG) "'"
           DISPLAY "+100000 X'" FUNCTION HEX-OF(WS-FULL) "'"
           ADD 1 TO WS-STD WS-NATIVE
           DISPLAY "COMP   9999 + 1 = " WS-STD
           DISPLAY "COMP-5 9999 + 1 = " WS-NATIVE
           DISPLAY "PLAIN   " FUNCTION LENGTH(WS-PLAIN) " BYTES"
           DISPLAY "ALIGNED " FUNCTION LENGTH(WS-ALIGNED) " BYTES"
           STOP RUN.
+300    X'012C'
-1      X'FFFF'
+100000 X'000186A0'
COMP   9999 + 1 = +0000
COMP-5 9999 + 1 = +10000
PLAIN   8 BYTES
ALIGNED 12 BYTES

Picture vs. capacity

A halfword can hold up to 32,767, but PIC S9(4) promises four digits. Which one wins depends on the IBM compiler option TRUNC:

  • TRUNC(STD): results are cut to the picture. 9999 + 1 gives 0000. GnuCOBOL behaves like this by default.
  • TRUNC(BIN): the full binary range is kept. Slower, but safe when the value comes from a non-COBOL program or a system API.
  • TRUNC(OPT): the compiler does whatever is fastest. Code must never exceed the picture.

COMP-5 means native binary regardless of TRUNC. Use it for values exchanged with C, Java, or system services such as lengths returned by an API.

SYNC and slack bytes

The hardware reads binary fields fastest when a fullword starts on an address divisible by 4 and a halfword on one divisible by 2. SYNC (SYNCHRONIZED) asks the compiler to align the field, inserting unnamed slack bytes before it. Above, WS-ALIGNED grew from 8 to 12 bytes: 3 slack bytes after A-FLAG and 1 after A-CODE.

Modern z/Architecture handles unaligned data well, so SYNC is rare in new code. It matters when a record layout must match something that was aligned, such as a control block or a file written by an old program. Miss a slack byte and every following field shifts.

Where binary fields turn up

Counters, subscripts and lengths in working storage; record-length and count fields in file headers; RETURN-CODE; Db2 SMALLINT and INTEGER columns (S9(4) COMP and S9(9) COMP); CICS EIBCALEN. Money almost never. That's packed decimal's job.

On the job

In ISPF HEX mode a binary field has no sign nibble and no digits you can read directly. Convert it: X'000186A0' is 1×65536 + 134×256 + 160 = 100,000. A hex calculator is a normal part of the toolkit.

Check your understanding

1. What are the bytes of PIC S9(4) COMP holding -2?
2. A group has PIC X, then PIC S9(9) COMP SYNC. How many bytes before the binary field starts?
3. Which field reliably holds 25000?
4. Why do copybooks written for other systems sometimes need SYNC or FILLER bytes added?