MODULE 13 · MAINFRAME INTERNALS AND CAPSTONE · 3/10

Packed decimal at the byte level

18 min40 XPExercise

In an earlier module you learned that COMP-3 stores two digits per byte. On the job you need to go one step further: look at raw bytes in a dataset or a dump and read the number straight off them.

The layout

A packed field is a row of nibbles (half-bytes). Each nibble is one decimal digit, 0–9, and the very last nibble is the sign:

Sign nibble Meaning
C positive
D negative
F unsigned (positive)

PIC S9(7)V99 COMP-3 has 9 digits + 1 sign = 10 nibbles = 5 bytes. The value -1234.50 is stored as the digits 000123450 followed by D:

X'00 01 23 45 0D'

The decimal point is not stored anywhere. V99 exists only in the program, which is why two programs with different copybooks can read the same bytes as different amounts.

Run this to see the bytes of three packed fields:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PACKED.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-BALANCE   PIC S9(7)V99 COMP-3 VALUE -1234.50.
       01  WS-RATE      PIC S9(4)    COMP-3 VALUE +123.
       01  WS-COUNT     PIC 9(3)     COMP-3 VALUE 7.
       PROCEDURE DIVISION.
           DISPLAY "BALANCE " WS-BALANCE "  X'"
               FUNCTION HEX-OF(WS-BALANCE) "'  "
               FUNCTION LENGTH(WS-BALANCE) " BYTES"
           DISPLAY "RATE    " WS-RATE "  X'"
               FUNCTION HEX-OF(WS-RATE) "'  "
               FUNCTION LENGTH(WS-RATE) " BYTES"
           DISPLAY "COUNT   " WS-COUNT "  X'"
               FUNCTION HEX-OF(WS-COUNT) "'  "
               FUNCTION LENGTH(WS-COUNT) " BYTES"
           STOP RUN.
BALANCE -0001234.50  X'000123450D'  5 BYTES
RATE    +0123  X'00123C'  3 BYTES
COUNT   007  X'007F'  2 BYTES

S9(4) still needs 3 bytes: 4 digits + sign is 5 nibbles, and the compiler pads with a leading zero nibble. That is why mainframe shops declare packed fields with an odd number of digits: S9(7)V99, S9(5), S9(15)V99. Nothing is wasted.

Packed bytes are identical on z/OS and in GnuCOBOL. Only the text around them differs (EBCDIC vs ASCII).

Reading packed data in HEX mode

In ISPF you type HEX ON while browsing a dataset. Each record is shown as three rows: the characters, then the zone (left) nibble of every byte, then the numeric (right) nibble underneath. Read each packed field down, then across. This course's dataset viewer has a HEX button that does the same. For the record ACC001 with +1234.50:

ACC001..#E.C
444333002404
1330010135C3

Bytes 7–11 read down-and-across as 00 01 23 45 0C: +1234.50. The character row shows dots and random symbols there, because packed bytes aren't characters. On z/OS the text columns would be EBCDIC instead (ACC001 is CCCFFF over 133001), but the packed columns would look exactly the same.

Record lengths

A record with packed fields is binary data. It must be written to a fixed-length dataset (ORGANIZATION IS SEQUENTIAL), never a text file: a packed byte can be X'0D' or X'25', which text tools treat as line endings.

On the job

"What's in this field?" is a daily question. Browse the dataset in HEX, count bytes from the copybook to the field's offset, and read the nibbles. Tools like File-AID and File Manager will format a record through a copybook for you, but you still need to read raw hex when the copybook is wrong, which is exactly when things break.

Your task

The general ledger feed arrives as text, but the downstream mainframe system expects 12-byte fixed-length records with a packed amount. Write them.

Input, DD name TXNIN, line sequential:

Field Picture Positions
IN-ACCT X(6) 1–6
FILLER X 7
IN-AMT-TEXT X(12), e.g. -1234.50 8–19

Output, DD name TXNOUT, ORGANIZATION IS SEQUENTIAL, RECORD CONTAINS 12 CHARACTERS (no line breaks between records):

Field Picture Bytes
OUT-ACCT X(6) 1–6
OUT-AMOUNT S9(7)V99 COMP-3 7–11
OUT-TYPE X: D if the amount is negative, else C 12

Then display:

RECORDS WRITTEN: 004

Click Run, open the output dataset under Files and press HEX. Record 2 (ACC002 -1234.56) must read 00012345 6D in bytes 7–11. Find the sign nibble of each record.

Check your understanding

1. What are the bytes of PIC S9(5) COMP-3 holding -42?
2. A dump shows a packed field as X'00012F'. What is it?
fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.