In DFSORT, PD stands for packed decimal. A packed decimal field stores two decimal digits per byte: each byte is split into two 4-bit nibbles, and each nibble holds a digit 0–9. The last byte holds one digit in one nibble and the sign in the other (e.g. C or F for positive, D for negative). This is exactly how COBOL COMP-3 (and equivalent) numeric fields are stored. When you specify PD in SORT FIELDS, DFSORT interprets the key as a signed decimal number and compares numeric value. The length you give is the number of bytes (e.g. 4 bytes for a 7-digit COMP-3). Using CH or ZD on packed data—or PD on zoned or character data—produces wrong sort order because the byte layout is different. This page explains the PD format in detail: nibbles, sign, length calculation, when to use PD, and how it differs from ZD, CH, and BI.
In packed decimal, each byte holds two digits. The high nibble (first 4 bits) holds one digit and the low nibble (last 4 bits) holds another. So the byte X'12' represents the digits 1 and 2. The number 12345 in packed form is typically stored as three bytes: X'12', X'34', and X'5C'—where the last byte has 5 in one nibble and C (positive sign) in the other. So we write it as X'12345C'. For -12345, the last byte would be X'5D' (D = negative). This is not the same as the character string "12345", which in EBCDIC would be five bytes: X'F1F2F3F4F5' (one byte per character). So packed decimal is more compact than zoned (one digit per byte) and has a different byte layout. DFSORT PD tells the sort to read the key as this packed format and compare the numeric value.
The length you specify in SORT FIELDS for PD is always the number of bytes the field occupies. To compute it from the number of digits:
| Digits (e.g. PIC S9(n)) | Bytes (length in SORT FIELDS) | Example |
|---|---|---|
| 5 | 3 | PIC S9(5) COMP-3 → (5+1)/2 = 3 |
| 7 | 4 | PIC S9(7) COMP-3 → (7+1)/2 = 4 |
| 9 | 5 | PIC S9(9) COMP-3 → (9+1)/2 = 5 |
| 15 | 8 | PIC S9(15) COMP-3 → (15+1)/2 = 8 |
If you are unsure, check your COBOL copybook or record layout: the length in bytes is what you use in SORT FIELDS, not the digit count.
Use PD in SORT FIELDS like this:
1SORT FIELDS=(start,length,PD,direction)
Example: sort by a 4-byte packed amount at position 30, descending:
1SORT FIELDS=(30,4,PD,D)
Example: primary key character at 1–10, secondary key packed at 11–14, both ascending:
1SORT FIELDS=(1,10,CH,A,11,4,PD,A)
| Use case | Reason |
|---|---|
| COBOL COMP-3 (or equivalent) | Storage is two digits per byte, sign in last nibble. |
| Amounts, quantities, totals in packed form | Many mainframe files use COMP-3 for numeric fields. |
| Record layout says "packed" or "COMP-3" | Match the format to the actual storage. |
ZD (zoned decimal) is for data stored with one digit per byte—like COBOL DISPLAY numeric. Each byte is an EBCDIC character for a digit (0xF0–0xF9), and the sign is in the zone (high nibble) of the last byte. So the number 12345 in zoned form is five bytes: X'F1F2F3F4F5' (positive) or X'F1F2F3F4D5' (negative, D in zone of last byte). In packed form, 12345 is X'12345C' (three bytes). The byte sequences are completely different. If you use PD on a zoned field, DFSORT will read the wrong value (it expects two digits per byte) and the sort order will be wrong. If you use ZD on a packed field, same problem. So you must know how the field is actually stored and choose PD or ZD accordingly.
In the last byte of a packed decimal field, one nibble is the last digit (0–9) and the other is the sign. Common conventions on the mainframe: C and F for positive, D for negative. Some systems use other values. DFSORT understands the usual conventions and compares the numeric value correctly (negative less than zero less than positive). You do not need to change the data—just specify PD and the correct length.
Wherever DFSORT needs to interpret a numeric field—in INCLUDE/OMIT comparisons, or when building or editing in INREC/OUTREC—you specify the format. For a packed decimal field, use PD so that numeric comparisons and arithmetic (if supported) use the correct value. For example, to omit records where a 4-byte packed amount at position 20 is zero or negative, you would use a numeric test with format PD; using CH or ZD would misinterpret the bytes.
Imagine saving numbers by putting two digits in each little box (byte). So the number 12345 fits in three boxes: 12, 34, and 5 with a plus sign. That is packed decimal. The computer knows how to read it: first box 12, second 34, third 5 and plus. PD is the rule that tells the sort: "this part of the record is saved that way." So the sort compares the real numbers (smaller first or bigger first). If we used the "character" rule (CH), the sort would look at the boxes as if they were letters and get the order wrong. So we use PD when the key is stored in that compact two-digits-per-box form, like many numbers in mainframe files.
1. What does PD mean in DFSORT?
2. A COBOL field is PIC S9(7) COMP-3. What length do you specify in SORT FIELDS?
3. Where is the sign stored in a packed decimal (PD) field?
4. What happens if you use PD for a zoned decimal (DISPLAY) field?
5. Why must you not use CH for a COMP-3 (packed) field?