MainframeMaster

Handling Overflow

When you use SUM FIELDS= to add up a numeric field per group, the result is written back into the same byte range as the input field. If the total is larger than that field can hold, you get overflow. DFSORT gives you two behaviors: VLSHRT (variable-length short) and NOVLSHRT. With VLSHRT, the result is truncated to fit so the job continues—but you may lose high-order digits and the total can be wrong. With NOVLSHRT, overflow is not allowed: the step fails so you can increase the field size (e.g. via INREC) or fix the data. This page explains when overflow happens, how to specify VLSHRT and NOVLSHRT, how to avoid overflow by sizing the field correctly, and the trade-off between “keep running” and “guarantee correct totals.”

SUM Statement
Progress0 of 0 lessons

When Does Overflow Occur?

Overflow occurs when the sum of a numeric field across all records in a group is larger than the maximum value that can be stored in that field’s length and format. For example: a 5-byte zoned decimal (ZD) field holds 5 digits plus sign, so the maximum value is 99,999 (or -99,999). If you sum 100 records and each has a value of 10,000, the total is 1,000,000—6 digits. That does not fit in 5 digits, so you get overflow. Similarly, a 4-byte packed decimal (PD) holds 7 digits plus sign; if the sum exceeds 9,999,999 (or the negative equivalent), it overflows.

VLSHRT vs NOVLSHRT

VLSHRT (variable-length short): when the sum does not fit in the output field, DFSORT truncates the value to fit. The job continues and writes the truncated result. You may lose the most significant digits—for example a total of 1,234,567 in a 5-digit field might become 34,567 or a product-specific truncation. So the output can be wrong and there is no built-in signal that overflow happened. Use VLSHRT when you prefer the job not to abend and can accept possible data loss (e.g. non-critical reporting).

NOVLSHRT: when the sum overflows, DFSORT does not truncate. Instead, the step terminates with an error (e.g. an ICE message or abend). You then fix the cause: increase the field length (e.g. with INREC so the summed field is longer) or correct the data. Use NOVLSHRT when you need to guarantee that no overflow is silently lost—for example in financial or audit-sensitive totals.

VLSHRT vs NOVLSHRT
OptionBehavior on overflowWhen to use
VLSHRTIf sum overflows, truncate to fit in the field; job continuesAcceptable to lose digits; prefer no abend
NOVLSHRTIf sum overflows, do not truncate; step fails with errorNeed to guarantee correct totals; detect bad data or layout

Where to Specify the Option

You can specify VLSHRT or NOVLSHRT on the OPTION statement (e.g. OPTION NOVLSHRT) so it applies to the whole step, or in some products on the SUM statement (e.g. SUM FIELDS=(21,5,ZD),NOVLSHRT). If both are present, the SUM-level option may override for that SUM. The exact syntax and default (VLSHRT or NOVLSHRT) depend on your DFSORT version; see your installation’s documentation.

Example: require overflow check

text
1
2
3
OPTION NOVLSHRT SORT FIELDS=(1,8,CH,A) SUM FIELDS=(21,5,ZD),NOVLSHRT

If the sum of the 5-byte ZD at 21–25 overflows, the step will fail instead of truncating. You can then increase the field (e.g. INREC to put the value in a 7-byte or 8-byte field) and sum that instead.

Avoiding Overflow: Size the Field for the Maximum Sum

The safest way to avoid overflow is to make the summed field large enough for the largest possible total. Estimate: maximum sum ≈ maximum value per record × maximum number of records per group. Then choose a field length and format that can hold that number. For example, if the max value per record is 99,999 and you have up to 10,000 records per group, the max sum is 999,990,000 (9 digits). A 4-byte PD holds 7 digits + sign; a 5-byte PD holds 9 digits + sign. So you need at least 5 bytes packed, or the equivalent in ZD. Use INREC to build a record where the value to be summed is in a longer field (e.g. copy the original 5-byte amount into a 6-byte or 8-byte position), then specify that longer position and length in SUM FIELDS=. The sum is then written into the longer field and will not overflow as long as the length is sufficient.

Example: INREC to expand sum field

Input: amount at 21–25 (5-byte ZD). You expect up to 100,000 records per group and values up to 99,999, so the max sum is 9,999,900,000 (10 digits). Use INREC to copy the amount into a longer field (e.g. 6-byte PD at 26–31, which holds 11 digits + sign), then sort and sum that field.

text
1
2
3
INREC OVERLAY=(26,6,PD,21,5,ZD) SORT FIELDS=(1,8,CH,A) SUM FIELDS=(26,6,PD)

The exact INREC syntax for copying or converting one field into another (e.g. ZD to PD in a longer field) is product-dependent. The idea is: the field that SUM writes to is now 6 bytes PD at 26–31, which can hold a much larger total. Non-summed positions (e.g. 1–25) still come from the first record of the group; position 26–31 holds the sum.

Variable-Length Records

The names VLSHRT and NOVLSHRT also relate to how DFSORT handles variable-length (VB) records when record length is shorter than the maximum. In some products, VLSHRT improves performance or correctness for VB input; NOVLSHRT may be required when using SUM with variable-length data. If you use VB input and see unexpected truncation or abends with SUM, try NOVLSHRT or consult your manual for variable-length and SUM.

Explain It Like I'm Five

Imagine you have a small box that can only hold a number with 5 digits (like 99,999). You add up a lot of numbers and the total is 1,234,567. The box is too small. VLSHRT is like squeezing the number into the box by cutting off the front—you might get 34,567 in the box, but the real total was 1,234,567, so it’s wrong. NOVLSHRT is like the computer saying “I won’t put it in the box; I’ll stop and tell you to get a bigger box.” So you get a bigger box (a longer field) and try again. The “bigger box” in the computer is making the sum field longer with INREC.

Exercises

  1. Your amount field is 4-byte PD at 20–23. You sum by customer; the maximum records per customer is 50,000 and the max amount per record is 999,999. Can the sum overflow a 4-byte PD? What length PD would you need?
  2. Write OPTION and SUM control statements to sum a 5-byte ZD at 30–34 and to fail (not truncate) if the sum overflows.
  3. Why might a shop choose NOVLSHRT for financial totals even if it means more job failures?
  4. Describe how INREC can be used to avoid overflow when the input sum field is too short for the expected total.

Quiz

Test Your Knowledge

1. What happens when the sum of a numeric field is too large to fit in the output field (overflow)?

  • DFSORT always abends
  • With VLSHRT the result is truncated to fit (you may lose digits); with NOVLSHRT the step fails with an error so you can fix the field size or data
  • The field is automatically expanded
  • Only the first digit is kept

2. How do you prevent overflow when summing many large values?

  • Use VLSHRT so it never fails
  • Plan the output field size for the maximum possible sum (e.g. use INREC to build a longer field before SUM), or use NOVLSHRT to detect overflow and then increase the field
  • Sum only small fields
  • Use OPTION COPY

3. Where do you specify VLSHRT or NOVLSHRT?

  • Only in JCL
  • On the OPTION statement (e.g. OPTION NOVLSHRT) or on the SUM statement (e.g. SUM FIELDS=(...),NOVLSHRT)—exact syntax is product-dependent
  • Only on SUM
  • In INREC only

4. Why would you choose NOVLSHRT over VLSHRT?

  • NOVLSHRT is faster
  • When you need to guarantee that overflow is detected—silent truncation with VLSHRT can produce incorrect totals that are hard to spot
  • Only for variable-length records
  • VLSHRT is never used

5. You sum a 5-byte ZD field; the maximum value per record is 99999 and you have up to 1000 records per group. What is a safe approach?

  • 5 bytes is always enough
  • The maximum sum could be 99999 × 1000 = 99,999,000—that needs more than 5 digits. Use INREC to expand the sum field to at least 8 digits (e.g. 5 bytes PD or longer ZD) and sum that, or use NOVLSHRT to catch overflow
  • Use VLSHRT only
  • Sum only 100 records