Showing posts with label packed decimal. Show all posts
Showing posts with label packed decimal. Show all posts

Monday, 28 July 2014

COBOL USAGE Clause: DISPLAY, COMP, COMP-3, and COMP-5

A file copybook may show PIC 9(9), but that does not tell you how the value is stored. A COBOL USAGE clause answers that question. It tells Enterprise COBOL whether the field is stored as display digits, binary, packed decimal, native binary, or floating point.

COBOL USAGE clause diagram showing DISPLAY, COMP, COMP-3, and COMP-5 storage choices
Pick usage by data purpose.

What is the COBOL USAGE clause?

The USAGE clause specifies the format used to represent a data item in storage. If you do not code it for ordinary numeric or alphanumeric fields, COBOL normally treats the item as DISPLAY. That is easy to read, but it is not always the best choice for arithmetic.

Use USAGE deliberately for fields that appear in calculations, counters, subscripts, DB2 host variables, file records, and interface copybooks. A wrong usage can give bad values, wasted storage, slow arithmetic, or a mismatch with another program.

Quick comparison

Usage Meaning Common use
DISPLAY External decimal or character representation. Report fields, text files, SYSIN values, displayable numeric data.
COMP or BINARY Binary storage controlled by the picture size and compiler truncation rules. Counters, indexes, lengths, record counts.
COMP-3 or PACKED-DECIMAL Packed decimal storage, two decimal digits per byte except the sign nibble. Money, balances, quantities, packed fields in files and DB2 host variables.
COMP-5 Native binary storage using the full capacity of 2, 4, or 8 bytes. System interfaces, binary lengths, fields shared with C or assembler.
COMP-1 and COMP-2 Internal floating-point data. These items do not use a PICTURE clause. Scientific or engineering values with a wide range of scale.

DISPLAY usage

DISPLAY stores data in a readable external form. A numeric display field such as PIC 9(5) stores five digit characters. This is useful for printable reports, flat-file fields exchanged as text, and values that must be easy to inspect in a dump or editor.

01 WS-CUSTOMER-NO       PIC 9(5) USAGE DISPLAY.
01 WS-CUSTOMER-NAME     PIC X(30).

The tradeoff is arithmetic cost. When a display numeric field is used in arithmetic, COBOL must work with its numeric value rather than just its printable characters. For heavy calculations, binary or packed decimal fields are usually a better fit.

COMP and BINARY usage

COMP, COMPUTATIONAL, and BINARY are treated as binary forms in Enterprise COBOL. IBM documents the normal storage size as 2 bytes for 1 through 4 digits, 4 bytes for 5 through 9 digits, and 8 bytes for 10 through 18 digits.

01 WS-READ-COUNT        PIC S9(9) COMP VALUE 0.
01 WS-TABLE-SUB         PIC S9(4) COMP VALUE 1.

Binary fields work well for counters, subscripts, loop control, record counts, and lengths. Be careful with fields that leave your program in a file or message. Another program must use the same storage expectation, or the bytes will not mean the same value.

COMP-3 packed decimal usage

COMP-3 is the short form of PACKED-DECIMAL. Packed decimal stores two decimal digits in each byte, except the final half-byte also carries the sign. It is a common mainframe choice for money and business amounts because decimal precision matters.

01 WS-INVOICE-AMOUNT    PIC S9(7)V99 COMP-3.
01 WS-TAX-AMOUNT        PIC S9(5)V99 COMP-3.
01 WS-TOTAL-AMOUNT      PIC S9(8)V99 COMP-3.

IBM notes that packed decimal fields use storage most efficiently when they have an odd number of digits. For example, S9(7)V99 has nine digits, so the packed decimal bytes are used neatly with the sign nibble.

COMP-5 native binary usage

COMP-5 is native binary. IBM documents that a COMP-5 item can contain values up to the capacity of the binary field size, not only the value implied by the number of 9s in the PICTURE. This matters for interface fields.

01 WS-BUFFER-LENGTH     PIC 9(9) COMP-5.
01 WS-RETURN-CODE       PIC S9(9) COMP-5.

Use COMP-5 when a called routine, system service, C program, or assembler module expects a native binary value. Do not swap COMP and COMP-5 casually in a shared copybook. Check the compile options and interface rule first.

COMP-1 and COMP-2 usage

COMP-1 is single-precision internal floating point and COMP-2 is double-precision internal floating point. IBM documents COMP-1 as 4 bytes and COMP-2 as 8 bytes. These fields do not have a PICTURE clause.

01 WS-RATE-SHORT        USAGE COMP-1.
01 WS-RATE-LONG         USAGE COMP-2.

Floating point is not the usual choice for currency. Use packed decimal for account balances, invoice totals, interest posted to an account, and other business amounts where exact decimal behavior is expected.

How to choose the right usage

If the field is... Usually choose... Reason
Printed or read as text DISPLAY Readable and simple for reports, SYSIN, and display files.
A business amount COMP-3 Keeps decimal arithmetic suitable for money and packed file fields.
A counter or subscript COMP or COMP-5 Binary arithmetic is a good fit for whole-number loop values.
A field passed to C or assembler COMP-5 Native binary values match many low-level interface contracts.
A scientific measurement COMP-1 or COMP-2 Floating point supports a wide range of scale.

USAGE at group level

A USAGE clause can be specified at group level, and then it applies to elementary items inside the group. This can be useful, but it also hides detail. Many teams prefer coding usage on elementary numeric fields so copybook reviewers can see the storage format quickly.

01 WS-TOTALS.
   05 WS-ITEM-COUNT      PIC S9(9) COMP.
   05 WS-GROSS-AMOUNT    PIC S9(9)V99 COMP-3.
   05 WS-NET-AMOUNT      PIC S9(9)V99 COMP-3.

Do not mix usage casually in file copybooks. If a field is written to a dataset, another job may read the same bytes tomorrow morning. The data definition is part of the file contract.

Common mistakes

Using DISPLAY for every number

DISPLAY is easy to read, but it is a poor default for every calculated number. A record loop that adds totals millions of times should not use display numeric work fields just because the input file is display format.

Using floating point for money

Use COMP-3 for money unless your site has a specific rule that says otherwise. Floating point can represent a wide scale, but finance programs usually need exact decimal behavior.

Changing COMP to COMP-5 without checking interfaces

COMP-5 can use the full native binary capacity of the field. That is useful for interfaces, but it can change behavior compared with picture-limited binary fields. Test boundary values before changing a shared field.

Forgetting TRUNC and ARITH options

TRUNC affects binary items such as COMP and COMP-4. ARITH affects the maximum digits allowed in decimal arithmetic. Review compile options when a numeric field behaves differently after migration.

Related Mainframe Forum guides

For nearby topics, read COBOL Data Division complete guide, COBOL COMP-3 packed decimal, COBOL ARITH compiler option, COBOL TRUNC compiler option, and Working Storage vs Local Storage.

External references

IBM documents the USAGE clause, computational items, and numeric data storage.

FAQ

What is USAGE in COBOL?

USAGE tells COBOL how a data item is represented in storage, such as display, binary, packed decimal, native binary, or floating point.

Is COMP-3 the same as packed decimal?

Yes. In Enterprise COBOL, COMP-3 and PACKED-DECIMAL describe packed decimal storage.

When should I use COMP-5?

Use COMP-5 when a field must hold a native binary value, especially for system interfaces, C calls, assembler calls, lengths, and return codes.

Should money use COMP-1 or COMP-2?

No, not for normal business amounts. Money is usually better defined as COMP-3 because packed decimal fits exact decimal business arithmetic.

Sunday, 11 August 2013

COBOL ARITH Compiler Option: COMPAT vs EXTEND with Decimal Examples

A COBOL program that adds packed decimal amounts all night can fail or slow down because of a compile option chosen years earlier. The ARITH compiler option controls the maximum number of digits allowed in decimal arithmetic. Most shops run many programs with ARITH(COMPAT), but some finance, billing, and high-volume calculation programs need ARITH(EXTEND).

COBOL ARITH compiler option diagram comparing ARITH COMPAT 18 digits and ARITH EXTEND 31 digits
Choose precision before compile.

What is the COBOL ARITH compiler option?

ARITH tells Enterprise COBOL how much decimal precision the compiler should allow for fixed-point decimal operations. It affects packed decimal, zoned decimal, numeric-edited items, and numeric literals used in arithmetic expressions.

The two common settings are ARITH(COMPAT) and ARITH(EXTEND). The simple rule is this: use COMPAT when 18 decimal digits are enough, and use EXTEND only when the program truly needs decimal results up to 31 digits.

ARITH(COMPAT) vs ARITH(EXTEND)

Option Decimal digit support Typical use
ARITH(COMPAT) Up to 18 digits Standard business calculations where field sizes fit traditional COBOL decimal limits
ARITH(EXTEND) Up to 31 digits Large packed decimal calculations, high-value balances, interest calculations, and migrated code that defines larger decimal fields

When ARITH(COMPAT) is enough

ARITH(COMPAT) is usually enough when the program uses ordinary business fields such as account balances, counts, rates, quantities, and totals that stay within 18 digits. It also keeps behavior closer to older COBOL code, which is why many long-running applications still use it.

01 WS-INVOICE-AMOUNT PIC S9(9)V99 COMP-3.
01 WS-TAX-AMOUNT PIC S9(7)V99 COMP-3.
01 WS-INVOICE-TOTAL PIC S9(10)V99 COMP-3.

These fields do not need 31-digit arithmetic. Changing the program to ARITH(EXTEND) may not add value unless another expression in the program needs the larger intermediate result.

When ARITH(EXTEND) is needed

ARITH(EXTEND) is useful when a calculation can exceed 18 digits before the final result is stored. That can happen when a program multiplies large quantities by rates, rolls up many account balances, or works with long packed decimal fields from a file or Db2 table.

01 WS-LARGE-BALANCE PIC S9(18)V99 COMP-3.
01 WS-INTEREST-RATE PIC S9(3)V9(9) COMP-3.
01 WS-INTEREST-AMOUNT PIC S9(18)V99 COMP-3.
COMPUTE WS-INTEREST-AMOUNT =
WS-LARGE-BALANCE * WS-INTEREST-RATE

Even if the receiving field has a normal size, the intermediate arithmetic can need more room. That is the point where ARITH(EXTEND) deserves a closer look.

Performance tradeoff

The older article stated that ARITH(EXTEND) can be slower than ARITH(COMPAT). That is still a useful warning, but it should not be treated as one fixed percentage for every program. The cost depends on how much decimal arithmetic the program performs, how often the code path runs, and what other work dominates the step.

A batch job that spends most of its time waiting on file I/O may not show much difference. A calculation-heavy program that runs millions of decimal operations in a tight loop may show a measurable CPU change. Measure CPU time and elapsed time before and after changing the compile option.

How to review ARITH safely

1. Find large decimal fields

Search the Data Division for packed decimal, zoned decimal, and edited fields with large picture clauses. Pay special attention to fields near 18 digits and fields used in multiplication, division, or compound COMPUTE statements.

2. Check arithmetic expressions

Look for ADD, SUBTRACT, MULTIPLY, DIVIDE, and COMPUTE. The field receiving the answer is only part of the story. Intermediate results can be larger than the final field.

3. Run representative test data

Use test records that contain maximum expected values, not only happy-path values. A program can pass small test data and still fail month-end or year-end processing when balances are higher.

4. Compare CPU and output

Compile the program with the candidate option, run the same input, compare output files, and check CPU time. Keep the compile listing with the change record so the next developer can see why the option was chosen.

Common mistakes

Using EXTEND everywhere

ARITH(EXTEND) should solve a precision need. Do not apply it to every program just because one calculation failed. Start with the program and expression that need more decimal digits.

Ignoring NUMPROC and TRUNC

ARITH is not the only numeric compile option that matters. Numeric sign handling and binary truncation can also affect results. Review related settings such as COBOL NUMPROC compiler option and COBOL TRUNC compiler option when numeric behavior is under review.

Testing only the final field size

A receiving field can look safe while an intermediate result is not. Review the whole expression, especially multiplication and division statements with large decimal operands.

Quick decision checklist

Question Recommended action
Do all decimal fields and intermediate results stay within 18 digits? Keep ARITH(COMPAT) unless another project standard says otherwise.
Can an expression need 19 to 31 decimal digits? Test with ARITH(EXTEND) and compare output and CPU time.
Is the job calculation-heavy? Measure CPU before and after the change with production-like input volume.
Is the program being migrated to a newer compiler? Check the compiler migration notes and keep compile options documented.

Related Mainframe Forum guides

For nearby compiler settings, read COBOL DATA compiler option, COBOL NUMPROC compiler option, and COBOL TRUNC compiler option. For run-time tuning context, see COBOL performance tuning and COBOL data types.

External references

IBM documents the Enterprise COBOL ARITH compiler option, fixed-point arithmetic, and decimal data.

FAQ

What does ARITH do in COBOL?

ARITH controls the maximum number of decimal digits allowed in fixed-point decimal arithmetic during compilation.

What is the difference between ARITH(COMPAT) and ARITH(EXTEND)?

ARITH(COMPAT) supports up to 18 decimal digits. ARITH(EXTEND) supports up to 31 decimal digits for programs that need larger decimal arithmetic.

Does ARITH(EXTEND) make COBOL slower?

It can add CPU cost in decimal-heavy programs because larger intermediate decimal results may be used. The real effect depends on the program, so test with representative input.

Should every COBOL program use ARITH(EXTEND)?

No. Use ARITH(EXTEND) when the program needs more than 18 decimal digits. For ordinary 18-digit business arithmetic, ARITH(COMPAT) is often enough.

Tuesday, 30 July 2013

Easytrieve Field Definition: Name, Position, Length, and Type

An Easytrieve report prints the wrong value when a field starts at the wrong byte. Field definitions tell Easytrieve where each value begins, how many bytes it occupies, and whether the data is alphanumeric, numeric, packed decimal, unsigned packed, or binary.

Easytrieve field definition diagram showing field name start position length data type decimals HEADING and MASK
Define bytes first.

What is an Easytrieve field definition?

An Easytrieve field definition names one item inside a file record or a working storage area. For an input file, the definition normally gives the field name, start position, length, data type, and optional decimal positions. Report options such as HEADING and MASK can be added when the field is printed.

The field definition is usually coded below the FILE statement. Easytrieve uses it when the job reads the file, tests values, calculates totals, or prints report columns.

Basic syntax

field-name   start-location   field-length   data-type   [decimal-positions] +
             [HEADING 'literal'] [MASK 'edit-mask']

The old post listed the same parts, but the rewrite below shows how each part affects a real report.

Field definition parts

Part Meaning Example
field-name The name used later in IF, MOVE, DISPLAY, LINE, and calculations. PAY-NET
start-location The byte position in the record, counted from position 1. 90
field-length The number of bytes occupied by the field. 4
data-type How Easytrieve should read and process the bytes. P for packed decimal
decimal-positions The implied number of decimal places for numeric fields. 2

Simple input file example

This example defines a fixed personnel record. The fields are then used in a report line.

FILE PERSNL FB(150 1800)
     DEPT        1   3 N
     EMPNO       9   5 N
     NAME       17  20 A
     PAY-NET    90   4 P 2

JOB INPUT PERSNL
    IF DEPT = 910
        PRINT PAYRPT
    END-IF

REPORT PAYRPT LINESIZE 100
    TITLE 1 'DEPARTMENT 910 NET PAY'
    LINE DEPT EMPNO NAME PAY-NET

If PAY-NET starts at byte 91 instead of byte 90, the report can show bad packed data or fail when Easytrieve tries to treat the wrong bytes as a packed amount.

Choosing field names

Use field names that match the business meaning of the data. PAY-NET is easier to read than FIELD-4. A field name also needs to be unique enough for the program. When two files contain the same field name, qualify it with the file name, such as PERSNL:DEPT.

Start location and length

The start location is counted from the first byte of the record. The length is the storage length, not the display width that appears on a printed report.

NAME       17  20 A
ADDRESS    37  39 A
PAY-NET    90   4 P 2

In this layout, NAME uses bytes 17 through 36. ADDRESS starts at byte 37. That clean byte boundary is what prevents fields from bleeding into each other.

Easytrieve data types

Type Use it for Practical note
A Names, codes, descriptions, and other character data. Best for values that should print exactly as stored.
N Zoned/display numeric fields. Common for readable numeric fields in flat files.
P Packed decimal fields. Common for money and quantity values from COBOL files.
U Unsigned packed decimal fields. Use only when the field is not signed.
B Binary fields. Broadcom notes that Easytrieve binary fields are defined as B fields and should be 4 bytes or less in the cited sample.

Decimal positions

Decimal positions are implied. They are not stored as a visible decimal point in the input record. In the next example, AMOUNT is a five-byte numeric field with two decimal positions.

AMOUNT     40   5 N 2

A stored value of 00123 represents 1.23 when the field is treated as having two decimal places. Use decimal positions only for fields that are really numeric quantities. Do not define account numbers, employee numbers, or product codes with decimal positions just because they contain digits.

HEADING for report columns

HEADING gives a better column title when the field prints on a report. You can define it with the field or in the report section.

FILE PERSNL FB(150 1800)
     EMPNO       9   5 N HEADING 'EMPLOYEE NUMBER'
     PAY-NET    90   4 P 2 HEADING 'NET PAY'

Broadcom documents report-level heading syntax as the field name followed by heading literals in parentheses. Keep the field name outside the parentheses.

REPORT PAYRPT
    HEADING EMPNO ('EMPLOYEE' 'NUMBER')
    HEADING PAY-NET ('NET' 'PAY')
    LINE EMPNO PAY-NET

MASK for printed values

MASK controls how a value appears when it is printed. It is useful for commas, decimal points, signs, and leading zero suppression.

PAY-NET    90   4 P 2 HEADING 'NET PAY' MASK 'ZZZ,ZZ9.99'

Broadcom notes that MASK applies to fields printed through report output. It is not a general data conversion rule for every move to a non-printer file.

Working field definitions

You can also define working fields for calculations. These fields are not pulled directly from the input record position. They hold values created by the program.

DEFINE TAX-AMT    W  7 P 2
DEFINE NET-AFTER  W  7 P 2

JOB INPUT PERSNL
    TAX-AMT = PAY-NET * .20
    NET-AFTER = PAY-NET - TAX-AMT
    PRINT PAYRPT

Use working fields when a report needs a calculated value, a temporary total, or a reformatted copy of an input field.

Common mistakes

Using display length as storage length

A packed decimal amount may print as several characters but use fewer bytes in the record. Define the storage bytes, then use MASK for the printed look.

Defining identifiers as numeric quantities

A department code or employee number may contain only digits, but it is still an identifier. Avoid decimal positions and automatic totaling for identifier fields.

Putting the field name inside HEADING parentheses

For report-level headings, code HEADING EMPNO ('EMPLOYEE' 'NUMBER'). Coding HEADING (EMPNO 'EMPLOYEE') can produce a field-name expected error.

Copying a record layout without checking byte positions

A one-byte shift can damage every field after it. Check start position, length, and type against the copybook or file layout before using the field in production output.

Quick checklist

  • Confirm the field starts at the correct byte position.
  • Confirm the length is the storage length in bytes.
  • Use A for text and identifiers that should not calculate.
  • Use N, P, U, or B only when the field is truly numeric.
  • Add decimal positions only when the value has implied cents, rates, quantities, or similar scale.
  • Use HEADING for report column names.
  • Use MASK for printed formatting, not as a substitute for the correct data type.

Related Easytrieve guides

For nearby topics, read Easytrieve Basic Reporting, Easytrieve Basic Report Edit Field Definition, Easytrieve Report Calculation, Easytrieve Basic Conditions, Easytrieve Sorting, and Easytrieve VSAM File Handling.

External references

Technical notes in this refresh were checked against Broadcom binary field guidance, Broadcom HEADING syntax guidance, Broadcom MASK parameter guidance, and Broadcom field heading notes.

FAQ

What are the required parts of an Easytrieve field definition?

The usual required parts are field name, start location, field length, and data type. Numeric fields can also include decimal positions.

What does the start location mean in Easytrieve?

The start location is the byte position where the field begins in the input record, counted from position 1.

When should I use HEADING in Easytrieve?

Use HEADING when the printed report needs a clearer column name than the field name.

What is MASK used for in Easytrieve?

MASK controls how a printed value appears, such as commas, decimal points, signs, and leading zero suppression.

New In-feed ads