Beginner

Operators in COBOL

Learn arithmetic, comparison, and logical operators in COBOL - including the verbose verb-based syntax (ADD, SUBTRACT, MULTIPLY, DIVIDE) and the modern COMPUTE statement

COBOL takes a unique approach to operators that reflects its business-documentation philosophy. Where most languages use compact symbols like +, -, *, and /, COBOL offers two parallel styles: verbose English-like verbs (ADD, SUBTRACT, MULTIPLY, DIVIDE) and the more familiar symbolic syntax through the COMPUTE statement.

This dual nature is intentional. A 1960s payroll clerk reviewing source code could read MULTIPLY HOURS BY RATE GIVING GROSS-PAY as a business rule, while a modern programmer can write COMPUTE GROSS-PAY = HOURS * RATE for compactness. Both compile to the same instructions.

In this tutorial you will learn how COBOL handles arithmetic, comparisons, and logical conditions. You will also see how operator precedence works in COMPUTE, how rounding and overflow are handled with ROUNDED and ON SIZE ERROR, and how COBOL’s wordy comparisons (IS GREATER THAN, IS EQUAL TO) coexist with the familiar symbols (>, =, <).

Arithmetic with Verbs

COBOL’s original arithmetic style uses dedicated verbs for each operation. Each verb has a GIVING clause that names the result field, leaving the source operands unchanged.

Create a file named arithm.cob:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
IDENTIFICATION DIVISION.
PROGRAM-ID. ARITHM.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 NUM-A      PIC 9(3) VALUE 25.
01 NUM-B      PIC 9(3) VALUE 4.
01 RESULT     PIC 9(5) VALUE 0.
01 REMAINDER-V PIC 9(3) VALUE 0.

PROCEDURE DIVISION.
    ADD NUM-A TO NUM-B GIVING RESULT.
    DISPLAY "ADD       : " RESULT.

    SUBTRACT NUM-B FROM NUM-A GIVING RESULT.
    DISPLAY "SUBTRACT  : " RESULT.

    MULTIPLY NUM-A BY NUM-B GIVING RESULT.
    DISPLAY "MULTIPLY  : " RESULT.

    DIVIDE NUM-A BY NUM-B GIVING RESULT
        REMAINDER REMAINDER-V.
    DISPLAY "DIVIDE    : " RESULT
        " REMAINDER " REMAINDER-V.

    STOP RUN.

Notice that DIVIDE accepts an optional REMAINDER clause - a built-in way to get integer division and modulo in a single statement.

The COMPUTE Statement

For complex expressions, the verb-based syntax becomes cumbersome. The COMPUTE statement uses familiar infix operators: +, -, *, /, and ** (exponentiation). Standard mathematical precedence applies, and parentheses force evaluation order.

Create a file named compute.cob:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
IDENTIFICATION DIVISION.
PROGRAM-ID. COMPUTE-DEMO.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 PRINCIPAL    PIC 9(5)V99 VALUE 1000.00.
01 RATE         PIC V999    VALUE 0.050.
01 YEARS        PIC 9(2)    VALUE 3.
01 INTEREST     PIC 9(7)V99 VALUE 0.
01 TOTAL        PIC 9(7)V99 VALUE 0.
01 AVERAGE      PIC 9(3)V99 VALUE 0.

PROCEDURE DIVISION.
    COMPUTE INTEREST = PRINCIPAL * RATE * YEARS.
    DISPLAY "Simple interest : " INTEREST.

    COMPUTE TOTAL ROUNDED = PRINCIPAL * (1 + RATE) ** YEARS.
    DISPLAY "Compound total  : " TOTAL.

    COMPUTE AVERAGE ROUNDED = (10 + 20 + 35) / 3.
    DISPLAY "Average         : " AVERAGE.

    STOP RUN.

The ROUNDED keyword rounds the result to the precision of the target field rather than truncating. Without it, 35 / 3 would store 11.66 (truncated) instead of 11.67 (rounded).

Comparison and Logical Operators

COBOL supports both wordy and symbolic comparisons, and they are completely interchangeable. The verbose forms (IS GREATER THAN, IS EQUAL TO, IS NOT LESS THAN) read like English, while the symbolic forms (>, =, <) are familiar to programmers from other languages.

Logical conditions use the keywords AND, OR, and NOT. There is no short-circuit guarantee in standard COBOL, so both sides of a logical expression may be evaluated.

Create a file named compare.cob:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
IDENTIFICATION DIVISION.
PROGRAM-ID. COMPARE.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 AGE          PIC 9(3) VALUE 42.
01 INCOME       PIC 9(6) VALUE 55000.
01 STATUS-CODE  PIC X    VALUE "A".

PROCEDURE DIVISION.
    IF AGE IS GREATER THAN 18
        DISPLAY "Adult (verbose form)"
    END-IF.

    IF AGE > 18
        DISPLAY "Adult (symbolic form)"
    END-IF.

    IF AGE >= 21 AND INCOME > 50000
        DISPLAY "Qualifies for premium tier"
    END-IF.

    IF STATUS-CODE = "A" OR STATUS-CODE = "P"
        DISPLAY "Account is active or pending"
    END-IF.

    IF NOT (AGE < 18)
        DISPLAY "Not a minor"
    END-IF.

    STOP RUN.

COBOL also supports class condition tests like IS NUMERIC, IS ALPHABETIC, and IS POSITIVE. These let you check the contents of a field without an explicit comparison: IF AGE IS NUMERIC is true when every character in AGE is a digit.

Handling Arithmetic Errors

Because COBOL fields have fixed precision defined by their PIC clauses, a result that exceeds the target’s size is a real concern in business code. The ON SIZE ERROR clause lets you handle overflow without crashing the program.

Create a file named safemath.cob:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
IDENTIFICATION DIVISION.
PROGRAM-ID. SAFEMATH.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 SMALL-RESULT PIC 9(2) VALUE 0.
01 DIVISOR      PIC 9(2) VALUE 0.
01 DIVIDEND     PIC 9(3) VALUE 100.
01 QUOTIENT     PIC 9(3) VALUE 0.

PROCEDURE DIVISION.
    COMPUTE SMALL-RESULT = 50 + 75
        ON SIZE ERROR
            DISPLAY "Overflow: result too large for field"
        NOT ON SIZE ERROR
            DISPLAY "Sum stored as: " SMALL-RESULT
    END-COMPUTE.

    DIVIDE DIVIDEND BY DIVISOR GIVING QUOTIENT
        ON SIZE ERROR
            DISPLAY "Division error (likely divide by zero)"
        NOT ON SIZE ERROR
            DISPLAY "Quotient: " QUOTIENT
    END-DIVIDE.

    STOP RUN.

ON SIZE ERROR catches two conditions: a result too large to fit in the target field, and division by zero. The END-COMPUTE and END-DIVIDE scope terminators (introduced in COBOL 85) close the statement explicitly, which is the modern style.

Running with Docker

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Pull the GnuCOBOL image
docker pull esolang/cobol:latest

# Compile and run the arithmetic verb example
docker run --rm -v $(pwd):/app -w /app esolang/cobol sh -c 'cobc -x -free arithm.cob && ./arithm'

# Compile and run the COMPUTE example
docker run --rm -v $(pwd):/app -w /app esolang/cobol sh -c 'cobc -x -free compute.cob && ./compute'

# Compile and run the comparison example
docker run --rm -v $(pwd):/app -w /app esolang/cobol sh -c 'cobc -x -free compare.cob && ./compare'

# Compile and run the size-error example
docker run --rm -v $(pwd):/app -w /app esolang/cobol sh -c 'cobc -x -free safemath.cob && ./safemath'

Expected Output

Running arithm:

ADD       : 00029
SUBTRACT  : 00021
MULTIPLY  : 00100
DIVIDE    : 00006 REMAINDER 001

Running compute:

Simple interest : 0000150.00
Compound total  : 0001157.63
Average         : 021.67

Running compare:

Adult (verbose form)
Adult (symbolic form)
Qualifies for premium tier
Account is active or pending
Not a minor

Running safemath:

Overflow: result too large for field
Division error (likely divide by zero)

Operator Precedence

When using COMPUTE, COBOL follows standard mathematical precedence:

PrecedenceOperatorsDescription
1 (highest)**Exponentiation
2unary + -Sign
3* /Multiplication, division
4+ -Addition, subtraction

Within the same precedence level, evaluation is left-to-right. When in doubt - especially in financial calculations - use parentheses. They cost nothing and make business rules explicit to the next person who reads the code.

Key Concepts

  • Two arithmetic styles coexist: verbose verbs (ADD, MULTIPLY) read like English; COMPUTE uses familiar infix operators including ** for exponentiation.
  • GIVING keeps operands intact: ADD A TO B GIVING C leaves A and B unchanged. Without GIVING, the result lands in the second operand.
  • ROUNDED controls fractional results: precision is governed by the target field’s PIC clause; without ROUNDED, extra digits are truncated.
  • Comparisons are dual-form: IS GREATER THAN and > mean the same thing; use whichever fits the audience reading the code.
  • ON SIZE ERROR handles overflow and divide-by-zero without aborting the program - critical for long-running batch jobs.
  • Class conditions like IS NUMERIC and IS ALPHABETIC test field contents without a comparison expression.
  • Logical operators are wordy: AND, OR, and NOT - no && or ||. Standard COBOL does not guarantee short-circuit evaluation.
  • Scope terminators (END-COMPUTE, END-IF, END-DIVIDE) make modern COBOL safer than the original period-terminated style.

Running Today

All examples can be run using Docker:

docker pull esolang/cobol:latest
Last updated:

Comments

Loading comments...

Leave a Comment

2000 characters remaining