Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. COBOL Dictionary
  3. Decimal Precision (COMP-3 / PACKED-DECIMAL)

Decimal Precision (COMP-3 / PACKED-DECIMAL)

In COBOL, COMP-3 (packed decimal, also called PACKED-DECIMAL) is an internal numeric representation format essential for precise decimal arithmetic in financial, insurance, and government systems. Unlike the normal display format (DISPLAY), it packs two decimal digits into one byte, providing high memory efficiency and enabling fast arithmetic while maintaining decimal precision.

Syntax

*> -----------------------------------------------
*> COMP-3 / PACKED-DECIMAL — Basic declaration syntax
*> -----------------------------------------------

*> Signed integer type (COMP-3)
01 var-name  PIC S9(n) COMP-3.

*> Signed decimal type (COMP-3)
01 var-name  PIC S9(n)V9(m) COMP-3.

*> Declare with an initial value
01 var-name  PIC S9(7)V99 COMP-3 VALUE 0.

*> -----------------------------------------------
*> Arithmetic using COMP-3 variables
*> -----------------------------------------------

*> Use in a COMPUTE statement (example: price calculation)
COMPUTE WS-TOTAL ROUNDED = WS-PRICE * WS-QUANTITY.

*> Use in an ADD statement
ADD WS-TAX TO WS-TOTAL.

*> Use in a SUBTRACT statement
SUBTRACT WS-DISCOUNT FROM WS-TOTAL.

*> Use in a MULTIPLY statement
MULTIPLY WS-RATE BY WS-AMOUNT GIVING WS-RESULT ROUNDED.

*> -----------------------------------------------
*> Converting to DISPLAY format (for output)
*> -----------------------------------------------

*> COMP-3 variables can be displayed directly (auto-converted)
DISPLAY "Total amount: " WS-TOTAL.

*> MOVE to a DISPLAY-format variable for formatted output
MOVE WS-TOTAL TO WS-TOTAL-DISPLAY.
DISPLAY "Total amount (formatted): " WS-TOTAL-DISPLAY.

Syntax Reference

Clause / SpecificationDescription
COMP-3Specifies that a numeric value is stored in packed decimal format. Can also be written as COMPUTATIONAL-3 or PACKED-DECIMAL.
PIC S9(n) COMP-3Declares a signed integer COMP-3 variable. Without S, negative values cannot be stored.
PIC S9(n)V9(m) COMP-3Declares a signed decimal COMP-3 variable. Allocates n integer digits and m fractional digits.
ROUNDEDRounds the result when the fractional part of the arithmetic result exceeds the variable's precision. Important for maintaining accuracy in financial calculations.
ON SIZE ERRORSpecifies exception handling for when the arithmetic result exceeds the number of digits defined in the variable's PIC clause.
COMPUTE variable ROUNDED = expressionEvaluates an arithmetic expression, rounds the result, and stores it in a variable. Used for operations between COMP-3 variables.
ADD value TO variableAdds a value to a variable. Can be used directly with COMP-3 variables.
SUBTRACT value FROM variableSubtracts a value from a variable.
MULTIPLY value BY variable GIVING result-variableMultiplies and stores the result in another variable. The GIVING clause lets you get the result without modifying the original variable.
DISPLAY format (edit PIC)To format COMP-3 calculation results in a human-readable form, MOVE them to an edit PIC variable before output.
COMPUTATIONAL-3The full spelling of COMP-3. Behavior is identical.
PACKED-DECIMALThe ISO standard name. Can be used as a synonym for COMP-3 (dialect-dependent).

Sample Code

deathnote_comp3.cbl
*> deathnote_comp3.cbl — Sample for COMP-3 (packed decimal)
*> Uses DEATH NOTE characters to demonstrate
*> COMP-3 declarations, arithmetic, the ROUNDED clause, and ON SIZE ERROR
*>
*> Compile and run:
*>   cobc -free -x deathnote_comp3.cbl
*>   ./deathnote_comp3

IDENTIFICATION DIVISION.
PROGRAM-ID. DEATHNOTE-COMP3.

DATA DIVISION.
WORKING-STORAGE SECTION.

*> -----------------------------------------------
*> Investigation scores for the DEATH NOTE investigation team
*> PIC S9(5)V99 COMP-3 — signed, 5 integer digits, 2 fractional digits
*> -----------------------------------------------
*> Light Yagami's investigation score (Kira investigation)
01 WS-SCORE-LIGHT          PIC S9(5)V99 COMP-3 VALUE 98.50.
*> L Lawliet's investigation score
01 WS-SCORE-L              PIC S9(5)V99 COMP-3 VALUE 99.90.
*> Near's investigation score
01 WS-SCORE-NEAR           PIC S9(5)V99 COMP-3 VALUE 95.30.

*> -----------------------------------------------
*> For precise budget calculation (high-precision scores)
*> PIC S9(7)V9(4) COMP-3 — high precision: 7 integer digits, 4 fractional digits
*> -----------------------------------------------
*> Budget scores for each investigator (base values)
01 WS-BUDGET-LIGHT         PIC S9(7)V9(4) COMP-3 VALUE 5000.0000.
01 WS-BUDGET-L             PIC S9(7)V9(4) COMP-3 VALUE 8500.0000.
01 WS-BUDGET-MISA          PIC S9(7)V9(4) COMP-3 VALUE 3200.5000.

*> -----------------------------------------------
*> Result and work variables (all unified as COMP-3)
*> -----------------------------------------------
*> Total investigation score
01 WS-SCORE-TOTAL          PIC S9(7)V99 COMP-3 VALUE 0.
*> Average investigation score
01 WS-SCORE-AVG            PIC S9(5)V99 COMP-3 VALUE 0.
*> Adjusted value (multiplication result)
01 WS-SCORE-ADJUSTED       PIC S9(7)V9(4) COMP-3 VALUE 0.
*> Difficulty bonus coefficient (1.1500)
01 WS-DIFFICULTY-FACTOR    PIC S9(1)V9(4) COMP-3 VALUE 1.1500.
*> Total budget score
01 WS-BUDGET-TOTAL         PIC S9(9)V9(4) COMP-3 VALUE 0.
*> Average budget score
01 WS-BUDGET-AVG           PIC S9(7)V9(4) COMP-3 VALUE 0.
*> Overflow test variable (5-digit integer only)
01 WS-OVERFLOW-TEST        PIC S9(5) COMP-3 VALUE 99999.

*> -----------------------------------------------
*> For output (edit PIC) — MOVE COMP-3 to DISPLAY format for formatting
*> -----------------------------------------------
01 WS-OUT-SCORE            PIC ZZ9.99.
01 WS-OUT-AVG              PIC ZZ9.99.
01 WS-OUT-BUDGET           PIC ZZZZ9.9(4).
01 WS-OUT-BUDGET-AVG       PIC ZZZZ9.9(4).
01 WS-OUT-ADJUSTED         PIC ZZZZ9.9(4).

PROCEDURE DIVISION.

    DISPLAY "====================================".
    DISPLAY "  DEATH NOTE — Investigation Score Analysis Report".
    DISPLAY "====================================".
    DISPLAY " ".

*> -----------------------------------------------
*> ADD / SUBTRACT — Aggregate investigation scores
*> Addition between COMP-3 variables runs as fast internal arithmetic
*> -----------------------------------------------
    DISPLAY "[ ADD — Investigation Score Total (COMP-3 addition) ]".

*> Add each person's score in sequence
    ADD WS-SCORE-LIGHT  TO WS-SCORE-TOTAL.
    ADD WS-SCORE-L      TO WS-SCORE-TOTAL.
    ADD WS-SCORE-NEAR   TO WS-SCORE-TOTAL.

*> MOVE COMP-3 variables to edit PIC for formatted display
    MOVE WS-SCORE-LIGHT  TO WS-OUT-SCORE.
    DISPLAY "  Light Yagami investigation score: " WS-OUT-SCORE.
    MOVE WS-SCORE-L      TO WS-OUT-SCORE.
    DISPLAY "  L Lawliet    investigation score: " WS-OUT-SCORE.
    MOVE WS-SCORE-NEAR   TO WS-OUT-SCORE.
    DISPLAY "  Near         investigation score: " WS-OUT-SCORE.
    MOVE WS-SCORE-TOTAL  TO WS-OUT-SCORE.
    DISPLAY "  Total                           : " WS-OUT-SCORE.
    DISPLAY " ".

*> -----------------------------------------------
*> COMPUTE ROUNDED — Average investigation score (with rounding)
*> ROUNDED is used when the fractional part exceeds precision
*> -----------------------------------------------
    DISPLAY "[ COMPUTE ROUNDED — Average Investigation Score ]".

*> Calculate the average of 3 investigators (round remainder after division)
    COMPUTE WS-SCORE-AVG ROUNDED = WS-SCORE-TOTAL / 3.
    MOVE WS-SCORE-AVG TO WS-OUT-AVG.
    DISPLAY "  Average investigation score (ROUNDED): " WS-OUT-AVG.
    DISPLAY " ".

*> -----------------------------------------------
*> MULTIPLY — Adjusted value with difficulty coefficient
*> GIVING clause preserves the original variable while storing result in another
*> -----------------------------------------------
    DISPLAY "[ MULTIPLY GIVING ROUNDED — Difficulty-adjusted score (L Lawliet) ]".

*> Apply difficulty bonus 1.15 to calculate adjusted investigation score
    MULTIPLY WS-DIFFICULTY-FACTOR BY WS-SCORE-L
        GIVING WS-SCORE-ADJUSTED ROUNDED.
    MOVE WS-SCORE-L         TO WS-OUT-SCORE.
    DISPLAY "  Before adjustment (L Lawliet): " WS-OUT-SCORE.
    MOVE WS-SCORE-ADJUSTED  TO WS-OUT-ADJUSTED.
    DISPLAY "  After adjustment             : " WS-OUT-ADJUSTED.
    DISPLAY " ".

*> -----------------------------------------------
*> High-precision (V9(4)) budget score aggregation
*> Handle 4 fractional digits with COMP-3, maintaining precision through arithmetic
*> -----------------------------------------------
    DISPLAY "[ COMPUTE — Budget Score Total and Average (4-decimal COMP-3) ]".

*> Sum the budget scores
    COMPUTE WS-BUDGET-TOTAL =
        WS-BUDGET-LIGHT + WS-BUDGET-L + WS-BUDGET-MISA.

*> Calculate the average of 3 (round digits beyond 4th decimal place with ROUNDED)
    COMPUTE WS-BUDGET-AVG ROUNDED = WS-BUDGET-TOTAL / 3.

    MOVE WS-BUDGET-LIGHT  TO WS-OUT-BUDGET.
    DISPLAY "  Light Yagami budget score: " WS-OUT-BUDGET.
    MOVE WS-BUDGET-L      TO WS-OUT-BUDGET.
    DISPLAY "  L Lawliet    budget score: " WS-OUT-BUDGET.
    MOVE WS-BUDGET-MISA   TO WS-OUT-BUDGET.
    DISPLAY "  Misa Amane   budget score: " WS-OUT-BUDGET.
    MOVE WS-BUDGET-AVG    TO WS-OUT-BUDGET-AVG.
    DISPLAY "  Average of 3             : " WS-OUT-BUDGET-AVG.
    DISPLAY " ".

*> -----------------------------------------------
*> ON SIZE ERROR — Overflow detection
*> Attempt to store 99999 squared (9999800001) in a PIC S9(5) variable
*> -----------------------------------------------
    DISPLAY "[ ON SIZE ERROR — COMP-3 overflow detection ]".
    DISPLAY "  Test variable (PIC S9(5) COMP-3) initial value: 99999".

    COMPUTE WS-OVERFLOW-TEST = WS-OVERFLOW-TEST * WS-OVERFLOW-TEST
        ON SIZE ERROR
            DISPLAY "  Overflow detected! The variable value was not changed."
        NOT ON SIZE ERROR
            DISPLAY "  Calculation succeeded: " WS-OVERFLOW-TEST
    END-COMPUTE.

    DISPLAY " ".
    DISPLAY "====================================".
    DISPLAY "  Kira investigation score analysis complete.".
    DISPLAY "====================================".

    STOP RUN.
cobc -free -x deathnote_comp3.cbl && ./deathnote_comp3
====================================
  DEATH NOTE — Investigation Score Analysis Report
====================================

[ ADD — Investigation Score Total (COMP-3 addition) ]
  Light Yagami investigation score:  98.50
  L Lawliet    investigation score:  99.90
  Near         investigation score:  95.30
  Total                           : 293.70

[ COMPUTE ROUNDED — Average Investigation Score ]
  Average investigation score (ROUNDED):  97.90

[ MULTIPLY GIVING ROUNDED — Difficulty-adjusted score (L Lawliet) ]
  Before adjustment (L Lawliet):  99.90
  After adjustment             :   114.8850

[ COMPUTE — Budget Score Total and Average (4-decimal COMP-3) ]
  Light Yagami budget score:  5000.0000
  L Lawliet    budget score:  8500.0000
  Misa Amane   budget score:  3200.5000
  Average of 3             :  5566.8333

[ ON SIZE ERROR — COMP-3 overflow detection ]
  Test variable (PIC S9(5) COMP-3) initial value: 99999
  Overflow detected! The variable value was not changed.

====================================
  Kira investigation score analysis complete.
====================================

Overview

In COBOL, COMP-3 (PACKED-DECIMAL) is an internal representation format that packs two decimal digits into one byte. While the normal DISPLAY format uses one byte per digit, COMP-3 stores an n-digit number in (n + 1) / 2 bytes, greatly improving memory efficiency. Furthermore, arithmetic maintains decimal precision as-is, so rounding errors that occur with floating-point numbers (COMP-1/COMP-2) do not arise. This is why COMP-3 has been used for decades in financial, insurance, and tax systems. When declaring, it is recommended to include the sign indicator S as in PIC S9(n)V9(m) COMP-3 (without it, negative results cannot be stored, causing arithmetic errors). Use the ROUNDED clause for rounding after arithmetic, and combine it with the ON SIZE ERROR clause to detect overflow. For screen output, MOVE the COMP-3 variable to an edit PIC variable (such as ZZZ9.99) before using DISPLAY for a readable format. For the basics of numeric PIC clauses, see PIC clause (numeric type). For arithmetic details with COMPUTE statements, see COMPUTE.

Common Mistakes

Mistake 1: COMP-3 byte size rounds up to the nearest byte even for odd digit counts

COMP-3 stores two digits per byte, with the last byte holding the final digit and the sign. PIC S9(5) COMP-3 has 5 digits, so it uses 3 bytes internally ((5 + 1) / 2 = 3). Even if you increase the digit count, the byte count is calculated by rounding up.

*> COMP-3 byte count is calculated as (n + 1) / 2
*> PIC S9(5) COMP-3 — 5 digits → (5+1)/2 = 3 bytes
*> PIC S9(7) COMP-3 — 7 digits → (7+1)/2 = 4 bytes
*> PIC S9(4) COMP-3 — 4 digits → (4+1)/2 = 2.5 → 3 bytes (rounded up)

*> Checking byte efficiency with Light Yagami's investigation analysis scores
01 WS-SCORE-5DIG    PIC S9(5) COMP-3 VALUE 12345.   *> 3 bytes
01 WS-SCORE-6DIG    PIC S9(6) COMP-3 VALUE 123456.  *> 4 bytes (same byte count as 5 digits... wait, different)

PROCEDURE DIVISION.
    DISPLAY "5-digit score: " WS-SCORE-5DIG.
    DISPLAY "6-digit score: " WS-SCORE-6DIG.
    STOP RUN.

Just as L Lawliet grasps accurate information, estimate COMP-3 byte counts in advance using the formula (n + 1) / 2. Be aware that 6 digits and 5 digits use different byte counts when declaring.

Mistake 2: Displaying a variable with V (decimal point) directly shows no decimal point

When you DISPLAY a variable declared with V (implied decimal point) such as PIC S9(5)V99 COMP-3 directly, the decimal point is not shown. This is because V only indicates the internal position and has no effect on display.

*> NG: Even with V, displaying directly shows no decimal point
01 WS-SCORE   PIC S9(5)V99 COMP-3 VALUE 98.50.

PROCEDURE DIVISION.
    DISPLAY "Near's score: " WS-SCORE.
    *> Result is displayed as "009850" with no decimal point
    STOP RUN.

Just as Misa Amane insists on a visible style, when you need to display with a decimal point, MOVE to an edit PIC variable (such as ZZ9.99) and then DISPLAY.

*> OK: MOVE to an edit PIC variable, then DISPLAY
01 WS-SCORE       PIC S9(5)V99 COMP-3 VALUE 98.50.
01 WS-SCORE-DISP  PIC ZZ9.99.

PROCEDURE DIVISION.
    MOVE WS-SCORE TO WS-SCORE-DISP.
    DISPLAY "Near's score: " WS-SCORE-DISP.
    *> Result: " 98.50" displays correctly
    STOP RUN.

Mistake 3: Precision beyond the PIC digit count is truncated after arithmetic

When the result of arithmetic exceeds the digit count or precision defined in the destination variable's PIC clause, the excess is truncated. Without the ROUNDED clause, no rounding occurs either.

*> NG: If the division result exceeds PIC precision, the fractional part is truncated
01 WS-TOTAL     PIC S9(7)V99 COMP-3 VALUE 293.70.
01 WS-AVG-NG    PIC S9(5)V99 COMP-3 VALUE 0.
01 WS-OUT-AVG   PIC ZZ9.99.

PROCEDURE DIVISION.
    COMPUTE WS-AVG-NG = WS-TOTAL / 3.
    *> 293.70 / 3 = 97.90... digits from the 3rd decimal place on are truncated
    MOVE WS-AVG-NG TO WS-OUT-AVG.
    DISPLAY "Average (truncated): " WS-OUT-AVG.
    STOP RUN.

Just as Light Yagami builds a perfect plan, for arithmetic requiring precision, either use the ROUNDED clause for rounding or make the destination variable's fractional digit count large enough in advance.

*> OK: Use the ROUNDED clause to round
01 WS-TOTAL     PIC S9(7)V99   COMP-3 VALUE 293.70.
01 WS-AVG-OK    PIC S9(5)V99   COMP-3 VALUE 0.
01 WS-OUT-AVG   PIC ZZ9.99.

PROCEDURE DIVISION.
    COMPUTE WS-AVG-OK ROUNDED = WS-TOTAL / 3.
    MOVE WS-AVG-OK TO WS-OUT-AVG.
    DISPLAY "Average (ROUNDED): " WS-OUT-AVG.
    *> Result: " 97.90" displays correctly
    STOP RUN.

If you find any errors or copyright issues, please .