CUCO study materials
CUCO study resources

Packed-Decimal Amount Field Losing Its Sign in a Daily Settlement File

CUCO · Put your knowledge to work in context.

All case studies

Packed-Decimal Amount Field Losing Its Sign in a Daily Settlement File

Northwind Mutual's nightly settlement job has run unchanged for six years. The input is a fixed-length file; the copybook describes AMT-DUE as PIC S9(7)V99 COMP-3, followed immediately by INVOICE-NO PIC X(10). Last month the upstream billing system was replaced. Its new extract writes AMT-DUE as PIC S9(9)V99 COMP-3 and lengthened the record by one byte, but the file header and the COBOL copybook were not updated. Since cutover, about 3% of records produce amounts with the wrong sign, and invoice numbers on the same records contain unprintable characters. The job does not abend; it posts the bad values. A junior developer proposes adding a SIGN clause and a larger picture to AMT-DUE in the working-storage copybook, leaving the file record layout untouched. The operations team wants an immediate fix before month-end close.

1. Explain, using the storage layout, why both the amount sign and INVOICE-NO are corrupted.

Read the worked answer

Packed decimal stores two digits per byte, with the sign in the low-order nibble. S9(7)V99 has 7 + 2 = 9 digits plus a sign nibble, so it occupies 10 nibbles = 5 bytes. S9(9)V99 has 11 digits plus a sign nibble, so it occupies 12 nibbles = 6 bytes.

The old copybook still reads 5 bytes for AMT-DUE. In the new record those 5 bytes contain the high-order 9 digits of an 11-digit amount; the remaining 2 low-order digits and the real sign are in byte 6. COBOL therefore interprets a digit nibble as the sign, which explains the arbitrary-looking sign. It also starts INVOICE-NO at byte 6, but the invoice actually begins at byte 7. INVOICE-NO therefore receives the leftover packed byte followed by only the first 9 characters of the invoice; the last invoice character is dropped and the unprintable packed byte appears in the invoice number.

Because the physical record is fixed-length and one byte longer, each READ may still advance to the next record, so the job does not necessarily abend. The corruption is a record-descriptor mismatch, not a missing SIGN clause.

2. Evaluate the junior developer's proposal and specify the minimum safe change.

Read the worked answer

Changing only the working-storage picture does not fix the file layout. The FD, the 01 record length, and every program sharing the copybook must agree with the physical record. If AMT-DUE alone is enlarged while the record description stays 15 bytes, the first 15 bytes of each 16-byte record are still read in the old positions, so the amount and invoice remain misaligned. A SIGN clause is irrelevant because packed decimal already carries a sign nibble.

The minimum safe change is:

  • Update the shared copybook so AMT-DUE is PIC S9(9)V99 COMP-3.
  • Update the FD/record length to 16 bytes, and any constants or header checks that assume 15.
  • Recompile every program that uses the copybook, not only the settlement job.
  • Coordinate the cutover with the upstream extract and reformat or reject the interim file.
  • Test with positive, negative, zero, and maximum amounts, and verify the byte immediately following the amount is not printable invoice data.

If the upstream cannot revert, a one-time conversion program that reads the new 16-byte layout and writes the old layout is safer than changing only one program.

3. What two concrete controls would detect this before posting?

Read the worked answer

Two controls that would catch the defect before posting are:

  1. Record-length and layout reconciliation. Compare the file header's declared record length and the copybook-derived length before processing. A 15-byte expectation against a 16-byte file should fail the step immediately. In addition, edit the invoice number for spaces and printable characters; the stray packed byte is a strong signal.
  2. Amount sign and range validation plus control totals. Reject amounts outside the business range, compare the count of negative adjustments with the source system's control count, and reconcile the total settled amount to an independent hash or control total. The wrong signs would not balance.

These controls are more reliable than waiting for an abend, because this failure mode posts plausible-looking values.