MODULE 3 · ARITHMETIC · 6/8

Numeric intrinsic functions

14 min30 XPExercise

COBOL has a library of built-in intrinsic functions. You call one with the word FUNCTION, its name, and arguments in parentheses, and you use it anywhere an arithmetic expression is allowed — usually inside COMPUTE:

           COMPUTE WS-HIGHEST = FUNCTION MAX(WS-A WS-B WS-C)

Arguments can be separated by spaces or commas.

The ones you'll use most

       IDENTIFICATION DIVISION.
       PROGRAM-ID. FUNCS.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-TEXT     PIC X(10) VALUE "  -1234.56".
       01  WS-R        PIC S9(5)V99.
       01  WS-OUT      PIC ---,--9.99.
       PROCEDURE DIVISION.
           COMPUTE WS-R = FUNCTION MOD(17, 5)
           DISPLAY "MOD(17, 5)        " WS-R
           COMPUTE WS-R = FUNCTION MOD(-7, 3)
           DISPLAY "MOD(-7, 3)        " WS-R
           COMPUTE WS-R = FUNCTION REM(-7, 3)
           DISPLAY "REM(-7, 3)        " WS-R
           COMPUTE WS-R = FUNCTION INTEGER(-3.7)
           DISPLAY "INTEGER(-3.7)     " WS-R
           COMPUTE WS-R = FUNCTION INTEGER-PART(-3.7)
           DISPLAY "INTEGER-PART(-3.7)" WS-R
           COMPUTE WS-R = FUNCTION MAX(3, 9.5, 2)
           DISPLAY "MAX(3, 9.5, 2)    " WS-R
           COMPUTE WS-R = FUNCTION SUM(3, 9.5, 2)
           DISPLAY "SUM(3, 9.5, 2)    " WS-R
           COMPUTE WS-R = FUNCTION NUMVAL(WS-TEXT)
           MOVE WS-R TO WS-OUT
           DISPLAY "NUMVAL            " WS-OUT
           STOP RUN.

Output:

MOD(17, 5)        +00002.00
MOD(-7, 3)        +00002.00
REM(-7, 3)        -00001.00
INTEGER(-3.7)     -00004.00
INTEGER-PART(-3.7)-00003.00
MAX(3, 9.5, 2)    +00009.50
SUM(3, 9.5, 2)    +00014.50
NUMVAL             -1,234.56
Function Returns
MOD(a, b) remainder with the sign of b (integers only)
REM(a, b) remainder with the sign of a
INTEGER(x) greatest integer ≤ x — rounds down, so -3.7 → -4
INTEGER-PART(x) drops the fraction — -3.7 → -3
MAX(...), MIN(...) largest / smallest argument
SUM(...) total of all arguments
NUMVAL(text) the number written in a text field

MOD and REM only differ for negative numbers, and INTEGER versus INTEGER-PART likewise. Choose deliberately — a date or bucket calculation that works for every positive test case can go wrong on the first refund.

NUMVAL: text to number

Data often arrives as text: a field from a CSV extract, a screen, a parameter card. You can't do arithmetic on " -1234.56" in a PIC X field. NUMVAL reads it the way a human would — leading and trailing spaces, a leading + or -, a decimal point, or a trailing -, CR or DB — and returns the value. For text with currency signs and thousands separators ($1,234.56) use NUMVAL-C instead.

Validate before NUMVAL

NUMVAL assumes the text is valid. Given "12A", GnuCOBOL quietly returns 12; other compilers may return garbage or abend. The function TEST-NUMVAL(text) returns 0 when the text is a valid number, or the position of the first bad character, so you can check first (you'll learn IF in the next module).

On the job

FUNCTION NUMVAL is everywhere in programs that read CSV or web-service data into mainframe files. FUNCTION CURRENT-DATE, INTEGER-OF-DATE and DATE-OF-INTEGER are the other intrinsic functions you'll meet constantly — they come up in a later module.

Your task

A reconciliation job receives three transaction amounts as text (one per line, read into PIC X(12) fields). They may have leading spaces, a minus sign, or a trailing CR for a credit.

Convert each with FUNCTION NUMVAL, then use intrinsic functions to show the total, the highest, the lowest and the average (rounded to the cent):

TOTAL:     1,475.25
HIGHEST:   1,250.50
LOWEST:      -75.25
AVERAGE:     491.75

That's the output for 1250.50, -75.25, 300. The display lines are in the starter.

fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.