It was 1997, and the year 2000 was approaching like a freight train. At a large insurance company in Hartford, Connecticut, a team of forty COBOL programmers was deep into a Y2K remediation project. Their mission: find every date calculation in...
In This Chapter
- Opening Vignette: The Function That Saved a Million Lines
- 19.1 What Are Intrinsic Functions?
- 19.2 Mathematical Functions
- 19.3 String Functions
- 19.4 Date and Time Functions
- 19.5 Numeric Conversion Functions
- 19.6 Boolean Functions
- 19.7 General Functions
- 19.8 Date Arithmetic Patterns
- 19.9 String Formatting Patterns
- 19.10 Statistical Analysis Patterns
- 19.11 Financial Calculation Patterns
- 19.12 Platform Support and Compatibility
- 19.13 Performance Considerations
- 19.14 Common Errors and Troubleshooting
- 19.15 Quick Reference Card
- 19.16 Chapter Summary
Chapter 19: Intrinsic Functions Reference
Opening Vignette: The Function That Saved a Million Lines
It was 1997, and the year 2000 was approaching like a freight train. At a large insurance company in Hartford, Connecticut, a team of forty COBOL programmers was deep into a Y2K remediation project. Their mission: find every date calculation in twenty million lines of COBOL code and fix it before the calendar rolled over. The work was tedious, error-prone, and achingly slow.
One of the junior programmers, fresh from a training course on the COBOL-85 Addendum, raised her hand during a team meeting. "Why are we writing custom date conversion routines?" she asked. "The compiler has intrinsic functions for this. FUNCTION INTEGER-OF-DATE converts any YYYYMMDD date to an integer. FUNCTION DATE-OF-INTEGER converts it back. We can do date arithmetic in one line of code."
The room went quiet. The senior developers looked at each other. Most of them had been writing COBOL since the 1970s, and many had never used an intrinsic function. They had always written their own subroutines for date calculations -- hundreds of lines of code to handle leap years, month boundaries, and century crossings. The intrinsic functions did all of that automatically, correctly, and in a single statement.
Within a week, the team had rewritten their date conversion strategy around intrinsic functions. What had been a 200-line copybook of date routines became a handful of COMPUTE statements. The code was cleaner, the testing was simpler, and the bugs were fewer. The project finished three months ahead of schedule.
This story, in various forms, played out at organizations around the world during the Y2K era. It was a powerful demonstration of a truth that many COBOL programmers had overlooked: the language had been quietly accumulating a library of built-in functions that could replace thousands of lines of hand-written code. These intrinsic functions -- for mathematics, string manipulation, date processing, financial calculations, and statistical analysis -- remain one of COBOL's most underused features to this day.
In this chapter, you will learn every intrinsic function available in modern COBOL, understand when and how to use each one, and see how they can dramatically simplify your programs.
19.1 What Are Intrinsic Functions?
Intrinsic functions are built-in functions provided by the COBOL language itself. Unlike user-written subroutines or called subprograms, intrinsic functions require no separate compilation, no CALL statement, and no LINKAGE SECTION. They are part of the compiler, available in any COBOL program simply by using the FUNCTION keyword.
History and Standards
Intrinsic functions were not part of the original COBOL language. They were introduced in the COBOL-85 Addendum (also known as the 1989 Amendment), which added 42 functions to the standard. This was a landmark addition -- for the first time, COBOL programmers had access to mathematical, string, and date functions without writing their own implementations.
The function library was expanded in subsequent standards:
- COBOL 2002 added functions like COMBINED-DATETIME, SECONDS-FROM-FORMATTED-TIME, TEST-DATE-YYYYMMDD, and TEST-DAY-YYYYDDD, among others.
- COBOL 2014 added modern string-handling functions including TRIM, CONCATENATE, and SUBSTITUTE, bringing COBOL's string capabilities closer to those of contemporary languages.
Today, IBM Enterprise COBOL and GnuCOBOL both support the vast majority of standard intrinsic functions, though there are minor differences in availability. We will note these differences throughout the chapter.
Basic Syntax
Every intrinsic function call follows the same pattern:
FUNCTION function-name(argument-1 [argument-2 ...])
Key syntax rules:
-
The FUNCTION keyword is required. Unlike languages such as Python or Java, where you simply write
sqrt(x), COBOL requires the explicitFUNCTIONkeyword:FUNCTION SQRT(x). -
Arguments are separated by spaces, not commas. This is a common source of confusion for programmers coming from other languages. You write
FUNCTION MAX(A B C), notFUNCTION MAX(A, B, C). -
Functions return values. A function call is an expression, not a statement. You use it in a COMPUTE, MOVE, IF, or DISPLAY statement -- anywhere a value is expected.
-
Functions do not modify their arguments. They are pure functions that produce a result without side effects (with the exception of RANDOM, which maintains internal state).
Using Functions in Statements
Intrinsic functions can appear anywhere a data value of the appropriate type is expected:
* In a COMPUTE statement
COMPUTE WS-RESULT = FUNCTION SQRT(WS-VALUE)
* In a MOVE statement
MOVE FUNCTION UPPER-CASE(WS-NAME)
TO WS-UPPER-NAME
* In a DISPLAY statement
DISPLAY "Square root: "
FUNCTION SQRT(144)
* In an IF condition
IF FUNCTION LENGTH(FUNCTION TRIM(WS-INPUT))
> 10
DISPLAY "Input exceeds 10 characters"
END-IF
* In arithmetic expressions
COMPUTE WS-AREA =
FUNCTION PI * WS-RADIUS ** 2
Nesting Functions
Functions can be nested -- the result of one function can serve as the argument to another:
* Trim, then convert to uppercase
MOVE FUNCTION UPPER-CASE(
FUNCTION TRIM(WS-FIELD))
TO WS-RESULT
* Square root of absolute value
COMPUTE WS-RESULT =
FUNCTION SQRT(
FUNCTION ABS(WS-VALUE))
* Length of trimmed content
COMPUTE WS-LEN =
FUNCTION LENGTH(
FUNCTION TRIM(WS-NAME))
When nesting functions, COBOL evaluates from the innermost function outward, just as you would expect from mathematical notation.
Function Categories
COBOL's intrinsic functions fall into six categories:
| Category | Count | Purpose |
|---|---|---|
| Mathematical | 34 | Arithmetic, trigonometry, statistics |
| String | 9 | Text manipulation and analysis |
| Date/Time | 12 | Date arithmetic and conversion |
| Numeric Conversion | 3 | Text-to-number conversion |
| Boolean | 2 | Boolean/integer conversion |
| General | 5 | Byte length, encoding, validation |
The following sections provide a complete reference for every function in each category.
19.2 Mathematical Functions
Mathematical functions form the largest category. They range from simple operations like absolute value to advanced statistical calculations.
Basic Arithmetic Functions
FUNCTION ABS(argument)
Returns the absolute value of its argument. The result is always non-negative.
COMPUTE WS-RESULT = FUNCTION ABS(-42.75)
* Result: 42.75
COMPUTE WS-RESULT = FUNCTION ABS(42.75)
* Result: 42.75
Return type: Same as argument type (integer if integer argument, numeric if numeric argument).
FUNCTION SIGN(argument)
Returns -1, 0, or +1 depending on whether the argument is negative, zero, or positive.
COMPUTE WS-RESULT = FUNCTION SIGN(-42)
* Result: -1
COMPUTE WS-RESULT = FUNCTION SIGN(0)
* Result: 0
COMPUTE WS-RESULT = FUNCTION SIGN(42)
* Result: +1
Return type: Integer.
FUNCTION INTEGER(argument)
Returns the greatest integer value that is not greater than the argument. This is the mathematical floor function.
COMPUTE WS-RESULT = FUNCTION INTEGER(3.7)
* Result: 3
COMPUTE WS-RESULT = FUNCTION INTEGER(-3.7)
* Result: -4 (floor rounds toward negative infinity)
Return type: Integer.
FUNCTION INTEGER-PART(argument)
Returns the integer portion of the argument by truncating toward zero. Unlike INTEGER, this function always truncates rather than flooring.
COMPUTE WS-RESULT = FUNCTION INTEGER-PART(3.7)
* Result: 3
COMPUTE WS-RESULT = FUNCTION INTEGER-PART(-3.7)
* Result: -3 (truncation toward zero, not -4)
Key difference from INTEGER: For positive numbers, INTEGER and INTEGER-PART produce the same result. For negative numbers, they differ. INTEGER(-3.7) = -4, but INTEGER-PART(-3.7) = -3.
Return type: Integer.
FUNCTION MOD(argument-1, argument-2)
Returns the value of argument-1 modulo argument-2. The result has the same sign as argument-2 (the divisor). Formally: MOD(a, b) = a - b * FUNCTION INTEGER(a / b).
COMPUTE WS-RESULT = FUNCTION MOD(17, 5)
* Result: 2
COMPUTE WS-RESULT = FUNCTION MOD(-17, 5)
* Result: 3 (sign follows divisor)
COMPUTE WS-RESULT = FUNCTION MOD(17, -5)
* Result: -3 (sign follows divisor)
Common use: Testing for even/odd numbers: FUNCTION MOD(N, 2) returns 0 for even, 1 for odd.
Return type: Same as argument type.
FUNCTION REM(argument-1, argument-2)
Returns the remainder of argument-1 divided by argument-2. The result has the same sign as argument-1 (the dividend). Formally: REM(a, b) = a - b * FUNCTION INTEGER-PART(a / b).
COMPUTE WS-RESULT = FUNCTION REM(17, 5)
* Result: 2
COMPUTE WS-RESULT = FUNCTION REM(-17, 5)
* Result: -2 (sign follows dividend)
COMPUTE WS-RESULT = FUNCTION REM(17, -5)
* Result: 2 (sign follows dividend)
Key difference from MOD: MOD and REM produce the same result for positive arguments. They differ when the dividend and divisor have different signs.
Return type: Same as argument type.
FUNCTION FACTORIAL(argument)
Returns the factorial of the argument (argument!). The argument must be a non-negative integer.
COMPUTE WS-RESULT = FUNCTION FACTORIAL(0)
* Result: 1
COMPUTE WS-RESULT = FUNCTION FACTORIAL(5)
* Result: 120 (5 * 4 * 3 * 2 * 1)
COMPUTE WS-RESULT = FUNCTION FACTORIAL(10)
* Result: 3628800
Note: Factorials grow extremely fast. FACTORIAL(20) = 2,432,902,008,176,640,000, which exceeds the capacity of most COBOL numeric fields. Use with caution for large arguments.
Return type: Integer.
FUNCTION SUM(argument-1 [argument-2 ...])
Returns the sum of all arguments.
COMPUTE WS-TOTAL = FUNCTION SUM(10 20 30 40)
* Result: 100
Return type: Same as argument type.
Exponential and Logarithmic Functions
FUNCTION SQRT(argument)
Returns the square root of the argument. The argument must be non-negative.
COMPUTE WS-RESULT = FUNCTION SQRT(144)
* Result: 12
COMPUTE WS-RESULT = FUNCTION SQRT(2)
* Result: 1.41421356... (approximation)
Return type: Numeric.
FUNCTION EXP(argument)
Returns e (Euler's number, approximately 2.71828) raised to the power of the argument.
COMPUTE WS-RESULT = FUNCTION EXP(0)
* Result: 1.0
COMPUTE WS-RESULT = FUNCTION EXP(1)
* Result: 2.71828... (e)
COMPUTE WS-RESULT = FUNCTION EXP(2)
* Result: 7.38905...
Return type: Numeric.
FUNCTION EXP10(argument)
Returns 10 raised to the power of the argument.
COMPUTE WS-RESULT = FUNCTION EXP10(2)
* Result: 100
COMPUTE WS-RESULT = FUNCTION EXP10(3)
* Result: 1000
Return type: Numeric.
FUNCTION LOG(argument)
Returns the natural logarithm (base e) of the argument. The argument must be positive.
COMPUTE WS-RESULT = FUNCTION LOG(1)
* Result: 0
COMPUTE WS-RESULT = FUNCTION LOG(2.71828)
* Result: approximately 1.0
Return type: Numeric.
FUNCTION LOG10(argument)
Returns the common logarithm (base 10) of the argument. The argument must be positive.
COMPUTE WS-RESULT = FUNCTION LOG10(100)
* Result: 2
COMPUTE WS-RESULT = FUNCTION LOG10(1000)
* Result: 3
Return type: Numeric.
Mathematical Constants
FUNCTION PI
Returns the value of pi (3.14159265...). Takes no arguments.
COMPUTE WS-CIRCUMFERENCE =
2 * FUNCTION PI * WS-RADIUS
COMPUTE WS-AREA =
FUNCTION PI * WS-RADIUS ** 2
FUNCTION E
Returns the value of Euler's number e (2.71828182...). Takes no arguments.
COMPUTE WS-RESULT = FUNCTION E
* Result: 2.71828182...
Trigonometric Functions
All trigonometric functions work in radians, not degrees. To convert degrees to radians, use: radians = degrees * FUNCTION PI / 180. To convert radians to degrees, use: degrees = radians * 180 / FUNCTION PI.
FUNCTION SIN(argument) -- Returns the sine of the argument (in radians).
FUNCTION COS(argument) -- Returns the cosine of the argument (in radians).
FUNCTION TAN(argument) -- Returns the tangent of the argument (in radians).
* Sine of 30 degrees
COMPUTE WS-ANGLE-RAD = 30 * FUNCTION PI / 180
COMPUTE WS-RESULT = FUNCTION SIN(WS-ANGLE-RAD)
* Result: 0.5
* Cosine of 60 degrees
COMPUTE WS-ANGLE-RAD = 60 * FUNCTION PI / 180
COMPUTE WS-RESULT = FUNCTION COS(WS-ANGLE-RAD)
* Result: 0.5
FUNCTION ASIN(argument) -- Returns the arc sine (in radians). Argument must be between -1 and 1.
FUNCTION ACOS(argument) -- Returns the arc cosine (in radians). Argument must be between -1 and 1.
FUNCTION ATAN(argument) -- Returns the arc tangent (in radians).
COMPUTE WS-RESULT = FUNCTION ASIN(0.5)
* Result: 0.5235... (pi/6, which is 30 degrees)
Trigonometric functions are rarely used in typical business COBOL programs, but they appear in engineering, scientific, and geographic information system (GIS) applications. Distance calculations using the haversine formula, for instance, require SIN, COS, ASIN, and SQRT.
Aggregate and Statistical Functions
These functions accept a variable number of arguments and compute aggregate values.
FUNCTION MAX(argument-1 argument-2 [...])
Returns the value of the largest argument. Arguments can be numeric or alphanumeric (but all must be the same type).
COMPUTE WS-HIGHEST = FUNCTION MAX(85 92 78 95 88)
* Result: 95
FUNCTION MIN(argument-1 argument-2 [...])
Returns the value of the smallest argument.
COMPUTE WS-LOWEST = FUNCTION MIN(85 92 78 95 88)
* Result: 78
FUNCTION ORD-MAX(argument-1 argument-2 [...])
Returns the ordinal position (1-based) of the argument with the maximum value.
COMPUTE WS-POS = FUNCTION ORD-MAX(85 92 78 95 88)
* Result: 4 (95 is the 4th argument)
FUNCTION ORD-MIN(argument-1 argument-2 [...])
Returns the ordinal position (1-based) of the argument with the minimum value.
COMPUTE WS-POS = FUNCTION ORD-MIN(85 92 78 95 88)
* Result: 3 (78 is the 3rd argument)
FUNCTION MEAN(argument-1 argument-2 [...])
Returns the arithmetic mean (average) of all arguments.
COMPUTE WS-AVG = FUNCTION MEAN(85 92 78 95 88)
* Result: 87.6 ((85+92+78+95+88) / 5)
FUNCTION MEDIAN(argument-1 argument-2 [...])
Returns the median value. For an odd number of arguments, this is the middle value when sorted. For an even number, it is the average of the two middle values.
COMPUTE WS-MED = FUNCTION MEDIAN(85 92 78 95 88)
* Result: 88 (sorted: 78 85 88 92 95; middle=88)
FUNCTION MIDRANGE(argument-1 argument-2 [...])
Returns the average of the maximum and minimum values: (max + min) / 2.
COMPUTE WS-MID =
FUNCTION MIDRANGE(85 92 78 95 88)
* Result: 86.5 ((95 + 78) / 2)
FUNCTION RANGE(argument-1 argument-2 [...])
Returns the difference between the maximum and minimum values.
COMPUTE WS-RNG = FUNCTION RANGE(85 92 78 95 88)
* Result: 17 (95 - 78)
FUNCTION VARIANCE(argument-1 argument-2 [...])
Returns the population variance -- the average of the squared deviations from the mean.
COMPUTE WS-VAR =
FUNCTION VARIANCE(85 92 78 95 88)
* Result: 32.56
FUNCTION STANDARD-DEVIATION(argument-1 argument-2 [...])
Returns the population standard deviation -- the square root of the variance.
COMPUTE WS-SD =
FUNCTION STANDARD-DEVIATION(85 92 78 95 88)
* Result: 5.7061...
Note on population vs. sample statistics: COBOL's VARIANCE and STANDARD-DEVIATION compute population statistics (dividing by N), not sample statistics (dividing by N-1). If you need sample statistics, you must adjust manually: multiply the variance by N/(N-1).
Financial Functions
FUNCTION ANNUITY(rate, periods)
Returns the ratio of an annuity paid at the end of each period for the specified number of periods at the given interest rate per period.
- If rate = 0: returns
1 / periods - If rate > 0: returns
rate / (1 - (1 + rate) ** -periods)
The primary use of ANNUITY is calculating loan payments:
* Monthly payment on a $200,000 mortgage
* at 5.5% annual rate for 30 years
COMPUTE WS-MONTHLY-PMT =
200000 * FUNCTION ANNUITY(
0.055 / 12, 360)
* Result: approximately $1,135.58
This single line replaces the complex formula that would otherwise require multiple COMPUTE statements.
FUNCTION PRESENT-VALUE(rate, cf-1 [cf-2 ...])
Returns the present value of a series of future cash flows discounted at the given rate per period.
The formula is: PV = cf1/(1+rate)^1 + cf2/(1+rate)^2 + ... + cfN/(1+rate)^N
* Present value of $10,000/year for 5 years at 8%
COMPUTE WS-PV =
FUNCTION PRESENT-VALUE(
0.08 10000 10000 10000 10000 10000)
* Result: approximately $39,927.10
FUNCTION RANDOM[(seed)]
Returns a pseudo-random number greater than or equal to 0 and less than 1.
- With a seed argument: initializes the random number sequence. The same seed always produces the same sequence (useful for testing).
- Without a seed: returns the next number in the current sequence.
* Initialize with seed
COMPUTE WS-R = FUNCTION RANDOM(12345)
* Generate next random number
COMPUTE WS-R = FUNCTION RANDOM
* Generate random integer 1-100
COMPUTE WS-INT =
FUNCTION INTEGER(FUNCTION RANDOM * 100) + 1
* Simulate a dice roll (1-6)
COMPUTE WS-DICE =
FUNCTION INTEGER(FUNCTION RANDOM * 6) + 1
Important: RANDOM is the only intrinsic function that maintains internal state. Each call without a seed returns the next value in a deterministic sequence. This is useful for simulations, testing, and Monte Carlo methods, but it is not suitable for cryptographic purposes.
19.3 String Functions
String functions provide text manipulation capabilities that were previously available only through the STRING, UNSTRING, and INSPECT statements or through custom subroutines.
FUNCTION UPPER-CASE(argument)
Returns the argument with all lowercase letters converted to uppercase. Non-letter characters are unchanged.
MOVE FUNCTION UPPER-CASE("Hello World")
TO WS-RESULT
* Result: "HELLO WORLD"
Common use: Case-insensitive comparisons:
IF FUNCTION UPPER-CASE(WS-INPUT) = "YES"
PERFORM 2000-PROCESS-YES
END-IF
FUNCTION LOWER-CASE(argument)
Returns the argument with all uppercase letters converted to lowercase.
MOVE FUNCTION LOWER-CASE("HELLO WORLD")
TO WS-RESULT
* Result: "hello world"
FUNCTION REVERSE(argument)
Returns the argument with characters in reverse order.
MOVE FUNCTION REVERSE("COBOL")
TO WS-RESULT
* Result: "LOBOC"
Practical use: Palindrome checking, right-to-left formatting, or quick string comparisons.
FUNCTION LENGTH(argument)
Returns the length (in character positions) of the argument.
COMPUTE WS-LEN = FUNCTION LENGTH("HELLO")
* Result: 5
COMPUTE WS-LEN = FUNCTION LENGTH(WS-NAME)
* Result: Length of PIC clause (includes trailing spaces)
Important: When applied to a data item, LENGTH returns the declared size of the field, including trailing spaces. To get the length of the actual content without trailing spaces, combine with TRIM:
COMPUTE WS-LEN =
FUNCTION LENGTH(FUNCTION TRIM(WS-NAME))
FUNCTION TRIM(argument [LEADING | TRAILING])
Introduced in COBOL 2014. Also supported as a GnuCOBOL extension.
Removes leading spaces, trailing spaces, or both from the argument.
* Remove both leading and trailing spaces (default)
MOVE FUNCTION TRIM(" Hello ")
TO WS-RESULT
* Result: "Hello"
* Remove only leading spaces
MOVE FUNCTION TRIM(" Hello " LEADING)
TO WS-RESULT
* Result: "Hello "
* Remove only trailing spaces
MOVE FUNCTION TRIM(" Hello " TRAILING)
TO WS-RESULT
* Result: " Hello"
Note: TRIM is one of the most useful functions introduced in COBOL 2014. Before its addition, removing leading or trailing spaces required complex INSPECT or reference modification logic.
FUNCTION ORD(argument)
Returns the ordinal position of the argument character in the collating sequence. The result is 1-based (the first character in the collating sequence has ordinal position 1).
In ASCII, ORD returns the ASCII code plus 1. For example, 'A' has ASCII code 65, so ORD('A') = 66.
COMPUTE WS-ORD = FUNCTION ORD("A")
* Result: 66 (ASCII) or 194 (EBCDIC)
FUNCTION CHAR(argument)
Returns the character at the specified ordinal position in the collating sequence. This is the inverse of ORD.
MOVE FUNCTION CHAR(66) TO WS-CHAR
* Result: "A" (in ASCII)
Roundtrip property: FUNCTION CHAR(FUNCTION ORD(x)) always equals x.
FUNCTION CONCATENATE(argument-1 argument-2 [...])
Introduced in COBOL 2014. Also supported as a GnuCOBOL extension.
Joins multiple string arguments into a single result.
MOVE FUNCTION CONCATENATE(
"Hello" " " "World")
TO WS-RESULT
* Result: "Hello World"
Note on trailing spaces: When concatenating PIC X fields, trailing spaces from each field are included in the result. Combine with TRIM for clean concatenation:
MOVE FUNCTION CONCATENATE(
FUNCTION TRIM(WS-FIRST)
" "
FUNCTION TRIM(WS-LAST))
TO WS-FULL-NAME
FUNCTION SUBSTITUTE(argument-1, old-1, new-1 [, old-2, new-2 ...])
Introduced in COBOL 2014. Also supported as a GnuCOBOL extension.
Replaces occurrences of old substrings with new substrings in argument-1. Multiple replacement pairs can be specified.
* Single replacement
MOVE FUNCTION SUBSTITUTE(
"Hello World" "World" "COBOL")
TO WS-RESULT
* Result: "Hello COBOL"
* Multiple replacements
MOVE FUNCTION SUBSTITUTE(
"The cat sat on the mat"
"cat" "dog"
"mat" "rug")
TO WS-RESULT
* Result: "The dog sat on the rug"
* Remove characters (replace with empty string)
MOVE FUNCTION SUBSTITUTE(
"555-123-4567" "-" "")
TO WS-RESULT
* Result: "5551234567"
19.4 Date and Time Functions
Date and time functions are arguably the most valuable category of intrinsic functions for business COBOL programming. They eliminate the need for custom date arithmetic routines and handle leap years, century boundaries, and calendar quirks automatically.
Getting the Current Date and Time
FUNCTION CURRENT-DATE
Returns a 21-character alphanumeric string containing the current date, time, and GMT offset.
| Position | Content | Format |
|---|---|---|
| 1-4 | Year | YYYY |
| 5-6 | Month | MM |
| 7-8 | Day | DD |
| 9-10 | Hours | HH |
| 11-12 | Minutes | MM |
| 13-14 | Seconds | SS |
| 15-16 | Hundredths | HH |
| 17 | GMT direction | + or - |
| 18-19 | GMT hours | HH |
| 20-21 | GMT minutes | MM |
01 WS-CURRENT-DATE-DATA.
05 WS-DATE.
10 WS-YEAR PIC 9(4).
10 WS-MONTH PIC 9(2).
10 WS-DAY PIC 9(2).
05 WS-TIME.
10 WS-HOURS PIC 9(2).
10 WS-MINUTES PIC 9(2).
10 WS-SECONDS PIC 9(2).
10 WS-HUNDREDTHS PIC 9(2).
05 WS-GMT-OFFSET.
10 WS-GMT-DIRECTION PIC X(1).
10 WS-GMT-HOURS PIC 9(2).
10 WS-GMT-MINUTES PIC 9(2).
MOVE FUNCTION CURRENT-DATE
TO WS-CURRENT-DATE-DATA
Note: CURRENT-DATE replaces the older ACCEPT statement with DATE, TIME, and DAY options. Unlike those older facilities, CURRENT-DATE provides the full four-digit year and timezone information.
FUNCTION WHEN-COMPILED
Returns the date and time the program was compiled, in the same 21-character format as CURRENT-DATE. This is useful for embedding version information in programs.
DISPLAY "Compiled on: "
FUNCTION WHEN-COMPILED(1:8)
Date Integer Conversion Functions
The core of COBOL's date arithmetic capability rests on two complementary functions that convert between calendar dates and integer day counts.
FUNCTION INTEGER-OF-DATE(yyyymmdd)
Converts a Gregorian date in YYYYMMDD format to an integer day number. The integer represents the number of days since a reference date (December 31, 1600, in the ISO standard; the Lilian date origin of October 14, 1582, in IBM Enterprise COBOL when compiled with INTDATE(LILIAN)).
COMPUTE WS-DAY-NUM =
FUNCTION INTEGER-OF-DATE(20240115)
FUNCTION DATE-OF-INTEGER(integer)
Converts an integer day number back to a Gregorian date in YYYYMMDD format.
COMPUTE WS-DATE =
FUNCTION DATE-OF-INTEGER(WS-DAY-NUM)
Date arithmetic pattern: The fundamental pattern for all date arithmetic in COBOL is:
- Convert dates to integers using INTEGER-OF-DATE
- Perform arithmetic on the integers
- Convert back to dates using DATE-OF-INTEGER
* Add 90 days to a date
COMPUTE WS-FUTURE =
FUNCTION DATE-OF-INTEGER(
FUNCTION INTEGER-OF-DATE(20240115) + 90)
* Result: 20240414
* Days between two dates
COMPUTE WS-DIFF =
FUNCTION INTEGER-OF-DATE(20241231) -
FUNCTION INTEGER-OF-DATE(20240101)
* Result: 365 (2024 is a leap year)
* Subtract 30 days from today
MOVE FUNCTION CURRENT-DATE TO WS-CD-DATA
COMPUTE WS-PAST =
FUNCTION DATE-OF-INTEGER(
FUNCTION INTEGER-OF-DATE(WS-DATE) - 30)
This pattern handles all calendar complexities automatically: leap years, varying month lengths, century boundaries, and so on.
Julian Date Functions
Julian dates use the format YYYYDDD, where DDD is the day of the year (1-365 or 1-366 for leap years).
FUNCTION INTEGER-OF-DAY(yyyyddd)
Converts a Julian date to an integer day number.
FUNCTION DAY-OF-INTEGER(integer)
Converts an integer day number to a Julian date.
* Convert Julian to Gregorian
COMPUTE WS-INT =
FUNCTION INTEGER-OF-DAY(2024100)
COMPUTE WS-GREGORIAN =
FUNCTION DATE-OF-INTEGER(WS-INT)
* Result: 20240409 (April 9, 2024)
* Convert Gregorian to Julian
COMPUTE WS-INT =
FUNCTION INTEGER-OF-DATE(20240704)
COMPUTE WS-JULIAN =
FUNCTION DAY-OF-INTEGER(WS-INT)
* Result: 2024186
Y2K Windowing Functions
These functions convert two-digit years to four-digit years using a sliding window technique. They were critical during Y2K remediation and remain useful when processing legacy data that still contains two-digit years.
FUNCTION YEAR-TO-YYYY(yy, window-start)
Converts a two-digit year to a four-digit year using a 100-year window. The window starts at (current-year - window-start) and extends 99 years forward.
* With window=50, if current year is 2024:
* Window is 1974-2073
COMPUTE WS-YEAR = FUNCTION YEAR-TO-YYYY(99, 50)
* Result: 1999 (99 falls in window 1974-2073)
COMPUTE WS-YEAR = FUNCTION YEAR-TO-YYYY(24, 50)
* Result: 2024
FUNCTION DATE-TO-YYYYMMDD(yymmdd, window-start)
Converts a six-digit date (YYMMDD) to an eight-digit date (YYYYMMDD) using the same windowing logic.
FUNCTION DAY-TO-YYYYDDD(yyddd, window-start)
Converts a five-digit Julian date (YYDDD) to a seven-digit Julian date (YYYYDDD).
Other Date/Time Functions
FUNCTION COMBINED-DATETIME(date-integer, time-seconds)
Combines a date integer (from INTEGER-OF-DATE) with seconds past midnight into a single numeric value. This is useful for precise date-time comparisons.
COMPUTE WS-DT =
FUNCTION COMBINED-DATETIME(
FUNCTION INTEGER-OF-DATE(20240115),
52245)
* 52245 = 14*3600 + 30*60 + 45 (2:30:45 PM)
FUNCTION SECONDS-PAST-MIDNIGHT
Returns the number of seconds past midnight as a numeric value. Takes no arguments.
COMPUTE WS-SECS = FUNCTION SECONDS-PAST-MIDNIGHT
* At 2:30:45 PM, result would be 52245.00
FUNCTION SECONDS-FROM-FORMATTED-TIME(format, time-string)
Converts a formatted time string to seconds past midnight.
COMPUTE WS-SECS =
FUNCTION SECONDS-FROM-FORMATTED-TIME(
"hh:mm:ss" "14:30:45")
* Result: 52245
Date Validation Functions
FUNCTION TEST-DATE-YYYYMMDD(date)
Validates a Gregorian date. Returns 0 if the date is valid; returns a nonzero value indicating the type of error if invalid.
IF FUNCTION TEST-DATE-YYYYMMDD(WS-DATE) = 0
DISPLAY "Date is valid"
ELSE
DISPLAY "Date is invalid"
END-IF
FUNCTION TEST-DAY-YYYYDDD(date)
Validates a Julian date. Returns 0 if valid; nonzero if invalid.
* Feb 29 in a non-leap year
COMPUTE WS-RESULT =
FUNCTION TEST-DATE-YYYYMMDD(20230229)
* Result: nonzero (2023 is not a leap year)
* Day 366 in a non-leap year
COMPUTE WS-RESULT =
FUNCTION TEST-DAY-YYYYDDD(2023366)
* Result: nonzero (2023 has only 365 days)
These validation functions are invaluable when processing date input from files, users, or external systems where data quality cannot be guaranteed.
19.5 Numeric Conversion Functions
These functions convert alphanumeric strings containing formatted numbers into actual numeric values.
FUNCTION NUMVAL(argument)
Converts an alphanumeric string to a numeric value. The string may contain: - Leading and trailing spaces - A leading or trailing sign (+ or -) - A decimal point - Trailing CR or DB (for credit/debit notation)
COMPUTE WS-NUM = FUNCTION NUMVAL(" 123.45 ")
* Result: 123.45
COMPUTE WS-NUM = FUNCTION NUMVAL(" -678.90")
* Result: -678.90
COMPUTE WS-NUM = FUNCTION NUMVAL(" 1234.56CR")
* Result: -1234.56 (CR indicates negative/credit)
FUNCTION NUMVAL-C(argument [, currency-char])
Like NUMVAL, but additionally handles currency symbols and comma thousands separators.
COMPUTE WS-NUM =
FUNCTION NUMVAL-C("$1,234.56")
* Result: 1234.56
COMPUTE WS-NUM =
FUNCTION NUMVAL-C("$12,345.67-")
* Result: -12345.67
FUNCTION NUMVAL-F(argument)
COBOL 2002 and later.
Converts an alphanumeric string containing a floating-point number (with optional exponent notation) to a numeric value.
COMPUTE WS-NUM =
FUNCTION NUMVAL-F("1.5E+03")
* Result: 1500.0
Practical use of NUMVAL/NUMVAL-C: These functions are essential when reading data from flat files or user input where numbers are stored as formatted text. Rather than manually stripping dollar signs, commas, and signs, you can convert the entire formatted string in one function call.
19.6 Boolean Functions
FUNCTION BOOLEAN-OF-INTEGER(integer, length)
Converts an integer value to a boolean (bit string) representation of the specified length.
FUNCTION INTEGER-OF-BOOLEAN(boolean)
Converts a boolean (bit string) value to an integer.
These functions are primarily used in specialized applications that work with bit-level data representations. They are less commonly encountered in typical business programming.
19.7 General Functions
FUNCTION BYTE-LENGTH(argument)
Returns the number of bytes occupied by the argument in storage. Unlike LENGTH, which returns the number of character positions, BYTE-LENGTH accounts for the actual storage format:
| USAGE | PIC | LENGTH | BYTE-LENGTH |
|---|---|---|---|
| DISPLAY | X(20) | 20 | 20 |
| DISPLAY | 9(7)V99 | 9 | 9 |
| PACKED-DECIMAL | 9(7)V99 | 9 | 5 |
| BINARY | 9(9) | 9 | 4 |
COMPUTE WS-BYTES =
FUNCTION BYTE-LENGTH(WS-PACKED-FIELD)
FUNCTION DISPLAY-OF(national-argument)
Converts a national (UTF-16) data item to its display (alphanumeric) representation.
FUNCTION NATIONAL-OF(argument)
Converts an alphanumeric data item to its national (UTF-16) representation.
These encoding functions are used in applications that must handle multiple character encodings, particularly in international environments.
19.8 Date Arithmetic Patterns
Date arithmetic is one of the most common applications of intrinsic functions in business programming. This section presents several patterns that appear frequently in production code.
Calculating Age
* Calculate age in years from birth date
MOVE FUNCTION CURRENT-DATE TO WS-CD-DATA
COMPUTE WS-AGE-DAYS =
FUNCTION INTEGER-OF-DATE(WS-TODAY) -
FUNCTION INTEGER-OF-DATE(WS-BIRTH-DATE)
COMPUTE WS-AGE-YEARS =
FUNCTION INTEGER-PART(WS-AGE-DAYS / 365.25)
The division by 365.25 (rather than 365) accounts for leap years in an approximate way. For exact age calculations in legal or regulatory contexts, you may need to compare the month and day components separately.
Adding or Subtracting Business Days
* Add N business days (skip weekends)
MOVE 0 TO WS-BIZ-DAYS-ADDED
MOVE FUNCTION INTEGER-OF-DATE(WS-START)
TO WS-CURR-INT
PERFORM UNTIL WS-BIZ-DAYS-ADDED >= WS-N
ADD 1 TO WS-CURR-INT
COMPUTE WS-DOW =
FUNCTION MOD(WS-CURR-INT, 7)
* Skip Saturday (6) and Sunday (0)
IF WS-DOW NOT = 0 AND WS-DOW NOT = 6
ADD 1 TO WS-BIZ-DAYS-ADDED
END-IF
END-PERFORM
COMPUTE WS-RESULT-DATE =
FUNCTION DATE-OF-INTEGER(WS-CURR-INT)
Finding the Last Day of a Month
* Last day of the current month
* Strategy: go to first of next month, subtract 1 day
IF WS-MONTH < 12
COMPUTE WS-NEXT-FIRST =
WS-YEAR * 10000 +
(WS-MONTH + 1) * 100 + 01
ELSE
COMPUTE WS-NEXT-FIRST =
(WS-YEAR + 1) * 10000 + 0101
END-IF
COMPUTE WS-LAST-DAY =
FUNCTION DATE-OF-INTEGER(
FUNCTION INTEGER-OF-DATE(WS-NEXT-FIRST)
- 1)
Determining the Day of the Week
* Day of week (0=Sunday through 6=Saturday)
COMPUTE WS-DOW =
FUNCTION MOD(
FUNCTION INTEGER-OF-DATE(WS-DATE), 7)
EVALUATE WS-DOW
WHEN 0 MOVE "Sunday" TO WS-DAY-NAME
WHEN 1 MOVE "Monday" TO WS-DAY-NAME
WHEN 2 MOVE "Tuesday" TO WS-DAY-NAME
WHEN 3 MOVE "Wednesday" TO WS-DAY-NAME
WHEN 4 MOVE "Thursday" TO WS-DAY-NAME
WHEN 5 MOVE "Friday" TO WS-DAY-NAME
WHEN 6 MOVE "Saturday" TO WS-DAY-NAME
END-EVALUATE
Note: the exact mapping between MOD results and days of the week depends on the epoch used by your compiler. The pattern shown here works with the standard ISO epoch (day 1 = January 1, 1601, which was a Monday). Test with a known date to verify the mapping for your environment.
19.9 String Formatting Patterns
Proper Case Formatting
Converting "JOHN SMITH" to "John Smith" requires character-level manipulation:
* Simple approach using reference modification
MOVE FUNCTION LOWER-CASE(WS-NAME)
TO WS-RESULT
MOVE FUNCTION UPPER-CASE(WS-RESULT(1:1))
TO WS-RESULT(1:1)
For names with spaces (first and last), you need to find each word boundary and capitalize the first letter. This is one area where COBOL's string functions, combined with INSPECT and reference modification, provide the necessary tools.
Building Formatted Output
* Build a formatted name: "Last, First M."
MOVE SPACES TO WS-FORMATTED
STRING
FUNCTION TRIM(WS-LAST-NAME)
DELIMITED BY SIZE
", " DELIMITED BY SIZE
FUNCTION TRIM(WS-FIRST-NAME)
DELIMITED BY SIZE
" " DELIMITED BY SIZE
WS-MIDDLE-INITIAL DELIMITED BY SIZE
"." DELIMITED BY SIZE
INTO WS-FORMATTED
END-STRING
Data Cleansing with SUBSTITUTE
* Remove unwanted characters from phone number
MOVE FUNCTION SUBSTITUTE(
WS-PHONE
"(" ""
")" ""
"-" ""
" " "")
TO WS-CLEAN-PHONE
19.10 Statistical Analysis Patterns
Computing Descriptive Statistics
When analyzing a dataset, a common pattern is to compute all descriptive statistics together:
COMPUTE WS-N = 10
COMPUTE WS-MEAN = FUNCTION MEAN(data args...)
COMPUTE WS-MED = FUNCTION MEDIAN(data args...)
COMPUTE WS-SD = FUNCTION STANDARD-DEVIATION(
data args...)
COMPUTE WS-LO = FUNCTION MIN(data args...)
COMPUTE WS-HI = FUNCTION MAX(data args...)
COMPUTE WS-RNG = FUNCTION RANGE(data args...)
Coefficient of Variation
The coefficient of variation (CV) expresses the standard deviation as a percentage of the mean, providing a normalized measure of dispersion:
COMPUTE WS-CV =
(FUNCTION STANDARD-DEVIATION(args...)
/ FUNCTION MEAN(args...)) * 100
A lower CV indicates more uniform data; a higher CV indicates greater variability.
Z-Score Calculation
To determine how many standard deviations a value is from the mean:
COMPUTE WS-Z-SCORE =
(WS-VALUE - FUNCTION MEAN(args...))
/ FUNCTION STANDARD-DEVIATION(args...)
19.11 Financial Calculation Patterns
Loan Payment Calculation
The ANNUITY function makes loan payment calculations trivial:
* Monthly payment = loan * ANNUITY(monthly-rate, months)
COMPUTE WS-PAYMENT =
WS-LOAN-AMOUNT *
FUNCTION ANNUITY(
WS-ANNUAL-RATE / 12,
WS-TERM-YEARS * 12)
Net Present Value (NPV) Analysis
* NPV = -initial-investment + PV of future cash flows
COMPUTE WS-NPV =
-1 * WS-INVESTMENT +
FUNCTION PRESENT-VALUE(
WS-DISCOUNT-RATE
WS-CF-YEAR-1
WS-CF-YEAR-2
WS-CF-YEAR-3
WS-CF-YEAR-4
WS-CF-YEAR-5)
IF WS-NPV > 0
DISPLAY "Investment is profitable"
ELSE
DISPLAY "Investment would lose money"
END-IF
Continuous Compounding
Using the EXP function to calculate continuous compounding:
* FV = PV * e^(rate * time)
COMPUTE WS-FUTURE-VALUE =
WS-PRESENT-VALUE *
FUNCTION EXP(WS-RATE * WS-YEARS)
19.12 Platform Support and Compatibility
IBM Enterprise COBOL
IBM Enterprise COBOL V6.x supports all standard intrinsic functions plus several IBM-specific extensions. Key considerations:
- INTDATE compiler option: Controls the epoch for INTEGER-OF-DATE. With INTDATE(ANSI), day 1 is January 1, 1601. With INTDATE(LILIAN), day 1 is October 15, 1582. The LILIAN option is the IBM default.
- TRIM, CONCATENATE, SUBSTITUTE: Supported starting with Enterprise COBOL V6.1.
- RANDOM: IBM's implementation uses a linear congruential generator with a period of approximately 2^48.
- NUMVAL/NUMVAL-C: Strict validation is performed; invalid input causes a runtime exception unless handled with ON EXCEPTION.
GnuCOBOL
GnuCOBOL 3.x supports the vast majority of standard intrinsic functions:
- Full support: All mathematical, string, date, and statistical functions are supported.
- TRIM, CONCATENATE, SUBSTITUTE: Supported as extensions, compatible with COBOL 2014 syntax.
- BOOLEAN-OF-INTEGER / INTEGER-OF-BOOLEAN: Limited support; availability depends on the GnuCOBOL version.
- COMBINED-DATETIME: Supported in recent versions.
- Epoch: GnuCOBOL uses the ISO/ANSI epoch (January 1, 1601 = day 1) by default.
Compatibility Table
| Function | Enterprise COBOL | GnuCOBOL 3.x | Standard |
|---|---|---|---|
| ABS, SIGN, INTEGER | Yes | Yes | COBOL-85 Amd |
| SQRT, LOG, LOG10 | Yes | Yes | COBOL-85 Amd |
| EXP, EXP10, FACTORIAL | Yes | Yes | COBOL-85 Amd |
| SIN, COS, TAN, ASIN, ACOS, ATAN | Yes | Yes | COBOL-85 Amd |
| PI, E | Yes | Yes | COBOL 2014 |
| MOD, REM | Yes | Yes | COBOL-85 Amd |
| MAX, MIN, ORD-MAX, ORD-MIN | Yes | Yes | COBOL-85 Amd |
| SUM | Yes | Yes | COBOL-85 Amd |
| MEAN, MEDIAN, MIDRANGE | Yes | Yes | COBOL-85 Amd |
| RANGE, VARIANCE, STANDARD-DEVIATION | Yes | Yes | COBOL-85 Amd |
| ANNUITY, PRESENT-VALUE | Yes | Yes | COBOL-85 Amd |
| RANDOM | Yes | Yes | COBOL-85 Amd |
| UPPER-CASE, LOWER-CASE | Yes | Yes | COBOL-85 Amd |
| REVERSE, LENGTH | Yes | Yes | COBOL-85 Amd |
| ORD, CHAR | Yes | Yes | COBOL-85 Amd |
| TRIM | V6.1+ | Yes | COBOL 2014 |
| CONCATENATE | V6.1+ | Yes | COBOL 2014 |
| SUBSTITUTE | V6.1+ | Yes | COBOL 2014 |
| CURRENT-DATE, WHEN-COMPILED | Yes | Yes | COBOL-85 Amd |
| INTEGER-OF-DATE, DATE-OF-INTEGER | Yes | Yes | COBOL-85 Amd |
| INTEGER-OF-DAY, DAY-OF-INTEGER | Yes | Yes | COBOL-85 Amd |
| DATE-TO-YYYYMMDD, YEAR-TO-YYYY | Yes | Yes | COBOL 2002 |
| DAY-TO-YYYYDDD | Yes | Yes | COBOL 2002 |
| COMBINED-DATETIME | Yes | Yes | COBOL 2002 |
| SECONDS-PAST-MIDNIGHT | Yes | Yes | COBOL 2002 |
| TEST-DATE-YYYYMMDD, TEST-DAY-YYYYDDD | Yes | Yes | COBOL 2002 |
| NUMVAL, NUMVAL-C | Yes | Yes | COBOL-85 Amd |
| NUMVAL-F | Yes | Limited | COBOL 2002 |
| BYTE-LENGTH | Yes | Yes | COBOL 2002 |
| BOOLEAN-OF-INTEGER | Yes | Limited | COBOL 2002 |
| INTEGER-OF-BOOLEAN | Yes | Limited | COBOL 2002 |
| DISPLAY-OF, NATIONAL-OF | Yes | Limited | COBOL 2002 |
19.13 Performance Considerations
Intrinsic functions are implemented by the compiler and generally perform well. However, there are some considerations worth noting.
Function Call Overhead
Each intrinsic function call has a small overhead compared to inline arithmetic. For most programs, this overhead is negligible. However, in tight loops processing millions of records, the cumulative cost can become measurable.
When functions are faster than manual code: - Date arithmetic: INTEGER-OF-DATE/DATE-OF-INTEGER is faster and more reliable than manual leap-year calculations - String case conversion: UPPER-CASE/LOWER-CASE is typically faster than INSPECT CONVERTING - Statistical functions: MEAN, VARIANCE, etc., are optimized for multiple arguments
When manual code may be faster:
- Simple operations like absolute value, where IF X < 0 COMPUTE X = X * -1 may be marginally faster than FUNCTION ABS(X) in some compilers
- When the function result is used repeatedly -- store it in a variable rather than calling the function multiple times
Precision Considerations
- Mathematical functions (SQRT, LOG, SIN, etc.) return results with the precision determined by the receiving field. Ensure your result field has enough decimal places.
- Statistical functions (VARIANCE, STANDARD-DEVIATION) can lose precision with very large datasets. For production statistical analysis on large datasets, consider using dedicated statistical software.
- RANDOM generates uniformly distributed numbers but is not suitable for cryptographic purposes.
Best Practices
-
Use functions instead of custom routines for date arithmetic, case conversion, and basic statistics. The built-in functions are tested, optimized, and handle edge cases correctly.
-
Store results in variables when the same function result is needed multiple times:
* Bad: calling the function twice
IF FUNCTION SQRT(X) > 10
MOVE FUNCTION SQRT(X) TO WS-RESULT
END-IF
* Good: call once, reuse the result
COMPUTE WS-SQRT = FUNCTION SQRT(X)
IF WS-SQRT > 10
MOVE WS-SQRT TO WS-RESULT
END-IF
-
Validate inputs before calling functions that have restricted domains (SQRT requires non-negative, LOG requires positive, ASIN/ACOS require -1 to 1).
-
Use TEST-DATE-YYYYMMDD before calling INTEGER-OF-DATE to avoid runtime errors on invalid dates.
-
Combine TRIM with CONCATENATE when building strings from PIC X fields to avoid unwanted trailing spaces.
19.14 Common Errors and Troubleshooting
Missing FUNCTION Keyword
* Wrong: missing FUNCTION keyword
COMPUTE WS-R = SQRT(WS-X)
* Correct
COMPUTE WS-R = FUNCTION SQRT(WS-X)
The compiler will typically report this as an undefined name or syntax error. Always include the FUNCTION keyword.
Using Commas Instead of Spaces
* Wrong: commas between arguments
COMPUTE WS-R = FUNCTION MAX(A, B, C)
* Correct: spaces between arguments
COMPUTE WS-R = FUNCTION MAX(A B C)
Note: Some compilers accept commas as separators, but the standard requires spaces. Use spaces for portability.
Invalid Domain Arguments
* Runtime error: SQRT of negative number
COMPUTE WS-R = FUNCTION SQRT(-4)
* Runtime error: LOG of zero
COMPUTE WS-R = FUNCTION LOG(0)
* Runtime error: invalid date
COMPUTE WS-R =
FUNCTION INTEGER-OF-DATE(20231301)
Always validate inputs before calling functions with restricted domains.
Receiving Field Too Small
* Truncation: FACTORIAL(10) = 3628800
* but PIC 9(5) can only hold up to 99999
01 WS-SMALL PIC 9(5).
COMPUTE WS-SMALL = FUNCTION FACTORIAL(10)
* Result will be truncated!
Ensure your receiving fields are large enough to hold the function's result.
INTEGER-OF-DATE Epoch Confusion
On IBM Enterprise COBOL, the result of INTEGER-OF-DATE depends on the INTDATE compiler option. The LILIAN and ANSI epochs produce different integer values for the same date. If you are comparing integer dates computed by different programs, ensure they use the same INTDATE setting.
19.15 Quick Reference Card
Mathematical Functions
| Function | Arguments | Returns | Since |
|---|---|---|---|
| ABS(x) | 1 numeric | Absolute value | 85 Amd |
| ACOS(x) | 1 numeric (-1 to 1) | Arc cosine (radians) | 85 Amd |
| ASIN(x) | 1 numeric (-1 to 1) | Arc sine (radians) | 85 Amd |
| ATAN(x) | 1 numeric | Arc tangent (radians) | 85 Amd |
| COS(x) | 1 numeric (radians) | Cosine | 85 Amd |
| E | none | Euler's number | 2014 |
| EXP(x) | 1 numeric | e^x | 85 Amd |
| EXP10(x) | 1 numeric | 10^x | 85 Amd |
| FACTORIAL(n) | 1 integer >= 0 | n! | 85 Amd |
| INTEGER(x) | 1 numeric | Floor of x | 85 Amd |
| INTEGER-PART(x) | 1 numeric | Truncation of x | 85 Amd |
| LOG(x) | 1 numeric > 0 | Natural log | 85 Amd |
| LOG10(x) | 1 numeric > 0 | Common log | 85 Amd |
| MOD(a, b) | 2 numeric | a modulo b | 85 Amd |
| PI | none | 3.14159... | 2014 |
| REM(a, b) | 2 numeric | Remainder | 85 Amd |
| SIGN(x) | 1 numeric | -1, 0, or +1 | 85 Amd |
| SIN(x) | 1 numeric (radians) | Sine | 85 Amd |
| SQRT(x) | 1 numeric >= 0 | Square root | 85 Amd |
| TAN(x) | 1 numeric (radians) | Tangent | 85 Amd |
Aggregate/Statistical Functions
| Function | Arguments | Returns | Since |
|---|---|---|---|
| MAX(a b ...) | 1+ numeric or alpha | Maximum value | 85 Amd |
| MEAN(a b ...) | 1+ numeric | Arithmetic mean | 85 Amd |
| MEDIAN(a b ...) | 1+ numeric | Median value | 85 Amd |
| MIDRANGE(a b ...) | 1+ numeric | (max+min)/2 | 85 Amd |
| MIN(a b ...) | 1+ numeric or alpha | Minimum value | 85 Amd |
| ORD-MAX(a b ...) | 1+ any | Position of max | 85 Amd |
| ORD-MIN(a b ...) | 1+ any | Position of min | 85 Amd |
| RANGE(a b ...) | 1+ numeric | max - min | 85 Amd |
| STANDARD-DEVIATION(a b ...) | 1+ numeric | Population std dev | 85 Amd |
| SUM(a b ...) | 1+ numeric | Sum of all | 85 Amd |
| VARIANCE(a b ...) | 1+ numeric | Population variance | 85 Amd |
Financial Functions
| Function | Arguments | Returns | Since |
|---|---|---|---|
| ANNUITY(rate, n) | 2 numeric | Annuity factor | 85 Amd |
| PRESENT-VALUE(rate, cf...) | 2+ numeric | Discounted PV | 85 Amd |
| RANDOM[(seed)] | 0 or 1 numeric | 0 <= r < 1 | 85 Amd |
String Functions
| Function | Arguments | Returns | Since |
|---|---|---|---|
| CHAR(n) | 1 integer | Character at position | 85 Amd |
| CONCATENATE(a b ...) | 1+ alphanumeric | Joined string | 2014 |
| LENGTH(x) | 1 any | Character count | 85 Amd |
| LOWER-CASE(x) | 1 alphanumeric | Lowercase string | 85 Amd |
| ORD(c) | 1 character | Ordinal position | 85 Amd |
| REVERSE(x) | 1 alphanumeric | Reversed string | 85 Amd |
| SUBSTITUTE(s, old, new...) | 3+ alphanumeric | Modified string | 2014 |
| TRIM(x [LEADING/TRAILING]) | 1 alphanumeric | Trimmed string | 2014 |
| UPPER-CASE(x) | 1 alphanumeric | Uppercase string | 85 Amd |
Date/Time Functions
| Function | Arguments | Returns | Since |
|---|---|---|---|
| COMBINED-DATETIME(d, t) | 2 numeric | Combined value | 2002 |
| CURRENT-DATE | none | 21-char date/time | 85 Amd |
| DATE-OF-INTEGER(n) | 1 integer | YYYYMMDD | 85 Amd |
| DATE-TO-YYYYMMDD(d, w) | 2 numeric | YYYYMMDD | 2002 |
| DAY-OF-INTEGER(n) | 1 integer | YYYYDDD | 85 Amd |
| DAY-TO-YYYYDDD(d, w) | 2 numeric | YYYYDDD | 2002 |
| INTEGER-OF-DATE(d) | 1 (YYYYMMDD) | Integer day | 85 Amd |
| INTEGER-OF-DAY(d) | 1 (YYYYDDD) | Integer day | 85 Amd |
| SECONDS-FROM-FORMATTED-TIME | 2 | Seconds | 2002 |
| SECONDS-PAST-MIDNIGHT | none | Seconds | 2002 |
| TEST-DATE-YYYYMMDD(d) | 1 (YYYYMMDD) | 0=valid | 2002 |
| TEST-DAY-YYYYDDD(d) | 1 (YYYYDDD) | 0=valid | 2002 |
| WHEN-COMPILED | none | 21-char date/time | 85 Amd |
| YEAR-TO-YYYY(y, w) | 2 numeric | YYYY | 2002 |
Numeric/General Functions
| Function | Arguments | Returns | Since |
|---|---|---|---|
| BOOLEAN-OF-INTEGER(n, len) | 2 | Boolean | 2002 |
| BYTE-LENGTH(x) | 1 any | Byte count | 2002 |
| DISPLAY-OF(x) | 1 national | Alphanumeric | 2002 |
| INTEGER-OF-BOOLEAN(b) | 1 boolean | Integer | 2002 |
| NATIONAL-OF(x) | 1 alphanumeric | National | 2002 |
| NUMVAL(x) | 1 alphanumeric | Numeric | 85 Amd |
| NUMVAL-C(x [,c]) | 1-2 | Numeric | 85 Amd |
| NUMVAL-F(x) | 1 alphanumeric | Numeric | 2002 |
19.16 Chapter Summary
Intrinsic functions transform COBOL from a language that requires you to write every calculation from scratch into one that provides a comprehensive library of pre-built capabilities. The key takeaways from this chapter are:
-
Syntax: Always use the FUNCTION keyword, separate arguments with spaces, and remember that functions return values -- they are expressions, not statements.
-
Date arithmetic is best done by converting to integers, performing arithmetic, and converting back. FUNCTION INTEGER-OF-DATE and FUNCTION DATE-OF-INTEGER are the cornerstones of this approach.
-
String functions -- especially TRIM, UPPER-CASE, LOWER-CASE, and CONCATENATE -- dramatically simplify text processing tasks that previously required complex INSPECT and STRING logic.
-
Statistical functions -- MEAN, MEDIAN, STANDARD-DEVIATION, VARIANCE, and RANGE -- provide built-in data analysis capabilities suitable for reporting and business intelligence applications.
-
Financial functions -- ANNUITY and PRESENT-VALUE -- replace complex formulas with single function calls for loan payment and investment analysis calculations.
-
Validation functions -- TEST-DATE-YYYYMMDD and NUMVAL/NUMVAL-C -- should be used to validate data before processing, catching errors early.
-
Functions can be nested, allowing you to compose complex operations from simple building blocks:
FUNCTION UPPER-CASE(FUNCTION TRIM(WS-FIELD)). -
Platform awareness is important: while most functions are available on both IBM Enterprise COBOL and GnuCOBOL, the COBOL 2014 string functions (TRIM, CONCATENATE, SUBSTITUTE) require recent compiler versions.
In the exercises that follow, you will practice using every category of intrinsic function in realistic programming scenarios.
Example programs for this chapter can be found in the code/ subdirectory. See example-01-math-functions.cob through example-06-practical-usage.cob for working demonstrations of every function discussed in this chapter.