Showing posts with label NUMCHECK. Show all posts
Showing posts with label NUMCHECK. Show all posts

Sunday, 11 August 2013

COBOL NUMPROC Compiler Option: PFD, NOPFD, and MIG Migration

A payroll program can compare two packed decimal fields correctly for years, then fail after one upstream file starts sending a non-preferred sign nibble. The NUMPROC compiler option tells Enterprise COBOL how much checking or correction it should do for signs in packed decimal and DISPLAY numeric data.

COBOL NUMPROC compiler option diagram comparing PFD, NOPFD, and MIG sign handling
Check numeric signs.

What is the COBOL NUMPROC compiler option?

NUMPROC controls how Enterprise COBOL treats numeric signs when it generates code for arithmetic, comparisons, and moves involving packed decimal and DISPLAY numeric items. It matters most when old files, hand-built test data, assembler routines, or converted applications can contain signs that do not match the preferred COBOL format.

The settings you will usually discuss are NUMPROC(PFD), NUMPROC(NOPFD), and older NUMPROC(MIG) migration behavior. For Enterprise COBOL 6, IBM documents that NUMPROC(MIG) is not supported the way it was in older compilers. The option is not a general performance switch. It is a data assumption. Pick it based on whether your input data always uses preferred signs.

NUMPROC(PFD), NOPFD, and MIG at a glance

Option Assumption Best fit
NUMPROC(PFD) Numeric data has preferred signs. Clean COBOL-created data where signs have already been verified.
NUMPROC(NOPFD) Signs may need generated code to handle non-preferred forms. Mixed-source data, old feeds, or files touched by non-COBOL programs.
NUMPROC(MIG) Legacy migration behavior from older compiler levels. Old compile decks and migration reviews; not a normal Enterprise COBOL 6 target setting.

What preferred signs mean

A signed packed decimal field stores the sign in the last half-byte. COBOL programs normally write preferred signs, but real production data does not always stay that neat. A file might be produced by assembler, copied from a different platform, repaired manually, or loaded by a utility that did not validate every numeric sign.

01 WS-GROSS-PAY     PIC S9(7)V99 COMP-3.
01 WS-DEDUCTION     PIC S9(7)V99 COMP-3.
01 WS-NET-PAY       PIC S9(7)V99 COMP-3.

If every value in those fields has a valid preferred sign, NUMPROC(PFD) lets the compiler generate shorter paths for many numeric operations. If the signs are not trustworthy, PFD can let bad data pass into comparisons or arithmetic without the extra generated handling you expected.

When NUMPROC(PFD) is a good choice

Use NUMPROC(PFD) when the program owns the data or every input feed has been checked. For example, a payroll calculation program that reads a VSAM file written only by COBOL programs, validates signed fields on input, and rejects bad records can often use PFD.

Do not choose PFD just because it may reduce CPU time. The option is safe only when the numeric data promise is true. One bad sign in a high-value record can be more expensive than a small CPU saving.

When NUMPROC(NOPFD) is safer

NUMPROC(NOPFD) is safer when signed numeric fields arrive from several sources. Common examples include old conversion files, test records copied from production, records updated by assembler, and feeds from distributed systems that were transformed before reaching z/OS.

IF CUSTOMER-BALANCE < ZERO
   PERFORM WRITE-CREDIT-REVIEW
END-IF

That comparison looks simple, but the compiler option decides how much sign handling is generated. If the file has suspect signs, keep the safer setting while you identify the source and clean the data.

Where NUMPROC(MIG) fits

NUMPROC(MIG) is mainly a legacy migration topic. If you find it in an old compile deck, treat that as a sign that the program needs migration review. IBM documents that Enterprise COBOL 6 does not support NUMPROC(MIG); if it is specified, the compiler issues a warning and uses the default NUMPROC setting.

A good migration plan compares compile listings, regression-test results, and records rejected by numeric checking. When the data is clean and test evidence is strong, move the program to the site standard option such as NUMPROC(NOPFD) or NUMPROC(PFD).

Use NUMCHECK during migration

For Enterprise COBOL migration work, NUMCHECK can help find invalid numeric data at run time. It is especially useful when a team wants to prove whether NUMPROC(PFD) is safe for a program. Use it in test or controlled verification runs, then review the records and code paths it reports.

//COBOL.SYSIN DD *
       PROCESS NUMPROC(NOPFD),NUMCHECK
/*

The exact compile syntax and suboptions depend on your compiler level and site defaults. Always check the compiler listing because the listing is the evidence of what the compiler actually used.

Safe review checklist

  • Find signed COMP-3 and DISPLAY numeric fields in the Data Division.
  • List every external file, Db2 extract, MQ message, and copybook feeding those fields.
  • Check whether non-COBOL programs can create or change the data.
  • Run representative test files with numeric checking before moving to NUMPROC(PFD).
  • Compare results for arithmetic, comparisons, and moves after the compile option change.
  • Record the final compiler option in the build standard, not only in one compile job.

Common mistakes

Using PFD because it sounds faster

PFD can generate more efficient code in some cases, but it is safe only when the data has preferred signs. The right question is not "Which option is faster?" The right question is "Can every signed numeric input be trusted?"

Leaving MIG forever

MIG is useful during migration, but a long-term compiler standard should be clear. If a program still needs migration behavior years later, document the reason and the data source that prevents cleanup.

Testing only clean data

A short unit test with perfect values does not prove the production file is safe. Include old records, rejected records, boundary amounts, negative balances, and records created by non-COBOL writers.

Related Mainframe Forum guides

For connected COBOL topics, read COBOL USAGE Clause, COBOL COMP-3 Packed Decimal, COBOL COMPUTE Statement, COBOL ARITH Compiler Option, COBOL OPTIMIZE Compiler Option, and COBOL Data Types.

External references

IBM documents the option in Enterprise COBOL NUMPROC, tuning guidance in NUMPROC migration and performance guidance, numeric checking in Enterprise COBOL NUMCHECK, and removed option behavior in compiler options not available in Enterprise COBOL.

FAQ

What does NUMPROC(PFD) mean in COBOL?

NUMPROC(PFD) tells the compiler to assume signed numeric data uses preferred signs. Use it only when input data has been verified.

Is NUMPROC(PFD) always faster?

No. It can reduce generated sign-handling code in some programs, but the visible performance effect depends on the workload. Correct numeric results come first.

When should I use NUMPROC(NOPFD)?

Use NOPFD when signed numeric data can come from old files, non-COBOL writers, conversions, or any source where signs may not be preferred.

Is NUMPROC(MIG) a permanent setting?

It is a legacy migration setting. In Enterprise COBOL 6, IBM documents that it is not supported and the compiler uses the default NUMPROC setting after a warning.

COBOL TRUNC Compiler Option: STD, OPT, and BIN Explained

01 BIN-VALUE PIC S9(4) COMP. has a four-digit COBOL PICTURE but normally occupies a two-byte binary field. The COBOL TRUNC compiler option decides whether moves and arithmetic respect the four decimal digits, assume that incoming data already fits them, or use the full native binary capacity.

COBOL TRUNC compiler option comparison for TRUNC STD, TRUNC OPT, TRUNC BIN, and COMP-5
TRUNC(STD) follows PICTURE digits, TRUNC(OPT) assumes conforming data, and TRUNC(BIN) uses native binary boundaries.

What the COBOL TRUNC option controls

TRUNC(STD|OPT|BIN) affects binary data during MOVE and arithmetic operations. In IBM Enterprise COBOL, BINARY, COMP, and COMP-4 are the relevant usages. The setting can change generated instructions and program results.

The option matters because a binary item's storage capacity can be wider than the decimal range stated by its PICTURE. A signed PIC S9(4) COMP item describes values through four decimal digits, yet its two-byte signed representation can hold a larger native range.

Scope: TRUNC does not control DISPLAY or packed-decimal fields, and it has no effect on COMP-5. The COBOL USAGE clause guide compares those storage formats.

TRUNC(STD): truncate to the PICTURE digits

TRUNC(STD) is the documented default. For a BINARY receiving field in a MOVE or arithmetic result, it truncates to the number of digits in that field's PICTURE. IBM identifies STD as the option that conforms to the 85 COBOL Standard.

01  BIN-VALUE  PIC S9(4) COMP.

    MOVE 12345 TO BIN-VALUE
    DISPLAY BIN-VALUE

Under STD, the receiving item is limited to four decimal digits, so the excess high-order digit is removed and the value is 2345. This is decimal or base-10 truncation; it is not a test for whether 12345 would physically fit in two bytes.

Choose STD when the program requires PICTURE-based truncation or when compatibility with that defined behavior matters more than the extra generated work.

TRUNC(OPT): assume data conforms to PICTURE

TRUNC(OPT) lets the compiler assume that values moved into BINARY areas conform to their PICTURE specifications. It can avoid the extra runtime truncation code generated by STD or BIN and generally provides the best performance of the three choices.

OPT is safe only when every value supplied to a BINARY item stays within its declared decimal precision. If the preceding example moves 12345 into PIC S9(4) COMP, that assumption is already false. IBM warns that the result can depend on the generated code sequence, so OPT must not be used to obtain a particular out-of-range value.

Data contract required: do not switch a program to TRUNC(OPT) solely for speed. First find binary fields populated by files, Db2, IMS, C, PL/I, assembler, copybooks, or calls where the producer might store values beyond the PICTURE digits.

TRUNC(BIN): use native binary boundaries

TRUNC(BIN) treats BINARY, COMP, and COMP-4 items as native hardware binary fields, as though each had been declared COMP-5. Receiving values are truncated at two-, four-, or eight-byte boundaries instead of the decimal PICTURE limit. Sending binary fields also use their full storage content when the receiver is numeric.

For the PIC S9(4) COMP example, 12345 fits in a signed two-byte field, so BIN preserves it even though it exceeds the four-digit PICTURE range. A still larger value can wrap or otherwise be truncated at the two-byte boundary.

IBM recommends BIN for programs that receive native binary values from other products when those values might not conform to the COBOL PICTURE. The tradeoff is generated code and intermediate handling: BIN is usually the slowest TRUNC choice.

TRUNC comparison table

OptionBinary ruleUse whenMain caution
TRUNC(STD)Truncates to decimal PICTURE digits.Defined PICTURE-based behavior or standard conformance is required.Generates extra work when BINARY receiving fields change.
TRUNC(OPT)Compiler assumes the value conforms to PICTURE and chooses an efficient sequence.All producers honor the declared precision and testing confirms it.Out-of-range data can produce unpredictable results.
TRUNC(BIN)Uses the full two-, four-, or eight-byte native binary field.External producers can supply valid native binary values beyond PICTURE digits.Usually the slowest option and changes DISPLAY/send behavior for binary data.

TRUNC and COMP-5 are not the same decision

A COMP-5 declaration is a data-item choice. That item always uses native binary behavior regardless of the program's TRUNC setting. By contrast, TRUNC(BIN) applies native behavior broadly to BINARY, COMP, and COMP-4 items throughout the compiled program.

Use COMP-5 when a specific copybook field has a native binary contract. This documents the requirement at the field and avoids changing unrelated COMP items. Use TRUNC(BIN) when the entire program requires that treatment or changing the copybook is not feasible.

Specify TRUNC in source or compilation JCL

A source option is direct and visible in the program:

CBL TRUNC(OPT)
IDENTIFICATION DIVISION.
PROGRAM-ID. PAYCALC.

The compiler option can also be passed to the compiler step:

//COBOL    EXEC PGM=IGYCRCTL,
//             PARM='TRUNC(OPT),LIST,MAP'
//SYSPRINT DD  SYSOUT=*
//SYSIN    DD  DSN=APP.COBOL(PAYCALC),DISP=SHR

If a cataloged compile procedure is used, qualify PARM with the procedure's internal compiler-step name, such as PARM.COBOL='TRUNC(OPT)'. The JCL cataloged procedure guide explains qualified EXEC overrides.

Always inspect the compiler listing. A site can set installation defaults or fix an option so that it cannot be overridden. The listing records the effective compiler options used for that load module.

Test before changing STD, OPT, or BIN

  1. Inventory BINARY, COMP, and COMP-4 fields, including copybooks.
  2. Identify values supplied by non-COBOL programs, subsystems, files, and calls.
  3. Compare each producer's native range with the receiving PICTURE digits.
  4. Compile a test version with NUMCHECK(BIN(TRUNCBIN)) when evaluating a move from BIN toward STD or OPT.
  5. Exercise maximum, minimum, negative, overflow, SIZE ERROR, and DISPLAY cases.
  6. Compare compiler listings and regression output before promotion.

NUMCHECK(BIN(TRUNCBIN)) can detect binary contents that exceed the PICTURE definition and would matter when moving away from TRUNC(BIN). It adds runtime checking, so use it as a controlled test aid rather than assuming it belongs permanently in a performance-sensitive build.

Common TRUNC mistakes

  • Assuming a value that fits the physical binary field also conforms to its PICTURE.
  • Expecting TRUNC to change COMP-5, COMP-3, or DISPLAY data.
  • Using OPT with unchecked binary values from another language or subsystem.
  • Setting BIN for every program when only one interface field needs COMP-5.
  • Changing the option and comparing only normal values rather than boundary cases.
  • Reading the JCL option but not confirming the effective value in the compiler listing.

TRUNC is only one numeric-code-generation decision. Review the COBOL ARITH compiler option for decimal intermediate precision and the COBOL SSRANGE option for subscript and reference-modification checks.

Selection checklist

  • Choose STD when PICTURE-digit truncation is the required result.
  • Choose OPT only when all BINARY data obeys its PICTURE and tests support the change.
  • Choose BIN when the full native binary value is part of an external data contract.
  • Choose COMP-5 for an individual field that explicitly needs native binary semantics.
  • Document the choice because a later compiler-option change can alter results without changing source statements.

For related compiler settings, see the COBOL DATA compiler option and the COBOL OPTIMIZE compiler option.

Official IBM references

COBOL TRUNC compiler option FAQ

What is the default COBOL TRUNC compiler option?

TRUNC(STD) is the documented default for current IBM Enterprise COBOL for z/OS. Installation defaults can be changed, so confirm the option listing for the compiled program.

Which COBOL fields are affected by TRUNC?

TRUNC controls BINARY, COMP, and COMP-4 processing in moves and arithmetic. It does not affect COMP-5 items, which always use native binary storage behavior.

When should TRUNC(BIN) be used?

Use it when binary fields can receive valid native binary values from Db2, IMS, C, PL/I, or another producer even when those values exceed the COBOL PICTURE digit limit.

Can changing TRUNC alter program results?

Yes. The setting changes runtime logic, so the same source can produce different values when a binary field contains data outside its PICTURE specification. Compile and regression-test before switching.

Treat TRUNC as part of the binary data contract: verify who writes each value, what its PICTURE promises, and which boundary the receiving program must enforce.

New In-feed ads