MainframeMaster

Numeric Comparisons in INCLUDE and OMIT

In DFSORT INCLUDE and OMIT, when the field you are testing is numeric—amounts, counts, IDs, or any value stored in a numeric format—you must specify the correct format in the condition so that DFSORT interprets the bytes as a number and compares by numeric value. The most common numeric formats in conditions are PD (packed decimal), ZD (zoned decimal), and BI (binary). Each has a different storage layout: packed decimal packs two digits per byte with a sign in the rightmost half-byte; zoned decimal uses one byte per digit with the sign in the last byte; binary is fixed-length two's complement. If you use CH (character) on a numeric field, the comparison is byte-by-byte by collating sequence, not by numeric value, and you can get wrong or unexpected results. This page explains how to use PD, ZD, and BI in COND=, how to choose the length, and how to write the comparison value (including negatives) so your numeric filters work correctly.

INCLUDE / OMIT Advanced Filtering
Progress0 of 0 lessons

Why Format Matters for Numeric Data

The same numeric value can be stored in different ways on the mainframe. For example, the number 12345 might be stored as packed decimal (bytes like x'12345C'), zoned decimal (one byte per digit with a zone and digit in each byte), or as a binary fullword. When you write COND=(start, length, format, operator, value), the format tells DFSORT how to decode those bytes into a number. If you use CH, DFSORT does not decode—it compares raw bytes. So the "number" 12345 as CH might compare incorrectly to 12345 as a constant because the byte representation is different. Always use the format that matches the way the field is actually stored in the record.

Common Numeric Formats in COND=

Numeric formats commonly used in INCLUDE/OMIT conditions
FormatNameTypical length (bytes)Use
PDPacked decimalVariable (e.g. 2–8)Signed decimal integers; 2 digits per byte + sign
ZDZoned decimalVariable (1 digit per byte)Signed decimal; sign in last byte (C/D etc.)
BIBinary2 (halfword) or 4 (fullword)Integer; fullword = 4 bytes
FIFixed pointProduct-dependentFixed-point numeric; see manual

PD — Packed Decimal

Packed decimal (PD) stores two decimal digits per byte, except the rightmost half-byte which holds the sign (e.g. C for positive, D for negative). So a 4-byte PD field holds 7 digits plus sign (e.g. -9999999 to +9999999). In COND= you specify the byte length: (start, length, PD, operator, value). Example: (20,4,PD,GT,0) tests the 4-byte packed field at positions 20–23 and keeps or omits when its value is greater than zero. The value is a numeric constant (e.g. 0, 100, -50). Use PD when your data is stored in packed form (common for amounts and counts in COBOL COMP-3 or equivalent).

ZD — Zoned Decimal

Zoned decimal (ZD) stores one digit per byte. The last byte also carries the sign (e.g. C or F for positive, D for negative in EBCDIC). So a 5-byte ZD field holds 5 digits plus sign. In COND= you use (start, length, ZD, operator, value). Example: (30,5,ZD,LE,99999) keeps records where the 5-byte zoned field at 30–34 is less than or equal to 99999. Zoned decimal is common in display or character-like numeric fields. Use ZD when the data is stored in zoned form (e.g. COBOL DISPLAY numeric).

BI — Binary

Binary (BI) is fixed-length two's complement (or unsigned, depending on context). A halfword is 2 bytes; a fullword is 4 bytes. In COND= you specify (start, length, BI, operator, value) where length is 2 or 4 (or 8 for doubleword if supported). Example: (40,4,BI,NE,0) tests the 4-byte binary at 40–43 and is true when the value is not zero. For very large or hex constants, your product may allow a special syntax (e.g. X'...'); see the manual. Use BI when the field is stored as binary (e.g. COBOL COMP or COMP-4).

Length and Position

Start is the starting byte position (1-based) of the field in the record. If you use INREC, positions refer to the record after INREC. Length is the number of bytes. For PD, length is the total byte count (e.g. 4 for a 7-digit + sign packed field). For ZD, length is the number of bytes (usually same as digit count for signed). For BI, length is 2 or 4 (or 8). Getting the length wrong can cause incorrect comparisons or abends: too short and you read part of the field; too long and you include the next field. Check your record layout or copybook.

Negative Values and Zero

You can compare numeric fields to negative constants. Example: INCLUDE COND=(20,4,PD,LT,0) keeps records where the packed amount is less than zero. For zoned decimal, the sign is in the last byte; DFSORT interprets it and compares correctly. For binary, negative numbers are in two's complement form. Zero is common: (30,4,PD,NE,0) keeps non-zero values; (30,4,PD,EQ,0) keeps only zero. Make sure the constant fits the range of the field (e.g. a 2-byte binary halfword has a limited range).

Examples

Keep records where packed-decimal amount at 25–28 is positive:

text
1
INCLUDE COND=(25,4,PD,GT,0)

Omit records where zoned-decimal code at 10–12 is zero:

text
1
OMIT COND=(10,3,ZD,EQ,0)

Keep records where 4-byte binary at 50–53 is greater than or equal to 1:

text
1
INCLUDE COND=(50,4,BI,GE,1)

Keep records where packed amount at 20–23 is between 100 and 500 (use AND):

text
1
INCLUDE COND=(20,4,PD,GE,100,AND,20,4,PD,LE,500)

Explain It Like I'm Five

Numbers can be written in different "languages" on the computer: packed is like writing two digits in one box, zoned is one digit per box, and binary is a different kind of code. When we tell the sort program "is this number bigger than 100?" we have to say which language the number is in (PD, ZD, or BI). If we say the wrong one, the computer reads the wrong thing—like reading a word in the wrong language—and the answer is wrong. So we always pick the format that matches how the number is actually stored.

Exercises

  1. Your record has a 5-byte packed-decimal field at position 40. Write INCLUDE COND= to keep records where that value is at least 1.
  2. What is the difference between (10,4,CH,GT,C'1000') and (10,4,PD,GT,1000)? Which one is correct for a packed-decimal amount?
  3. Write a condition to omit records where the 2-byte binary at position 60 is zero.
  4. How many bytes would you use for a 7-digit zoned-decimal field (with sign) in the length field of COND=?

Quiz

Test Your Knowledge

1. Why must you specify the correct format (PD, ZD, BI) for a numeric field in COND=?

  • It does not matter
  • So DFSORT interprets the bytes as a number—wrong format gives wrong comparison or errors
  • Only PD is supported
  • Only for INCLUDE

2. What is the length of a 4-byte fullword binary field in COND=?

  • 2
  • 4—BI length is in bytes
  • 8
  • Depends on the value

3. For packed decimal (PD), how is the length specified?

  • Number of digits
  • Number of bytes—PD stores 2 digits per byte (plus sign in last half-byte); length is byte count
  • Always 8
  • Double the digits

4. Can you compare a zoned decimal (ZD) field to a negative value?

  • No
  • Yes—ZD supports signed numbers; use a negative constant (e.g. -100) as the value
  • Only with OMIT
  • Only PD supports negative

5. What happens if the numeric constant is too large for the field?

  • DFSORT abends
  • Behavior is product-dependent; the comparison may still run but result can be wrong—use constants that match the field range
  • The constant is truncated
  • Only the field is used