Problem:
What are High-Values and Low-Values?
Resolution:
COBOL programmers sometimes use the figurative constants HIGH-VALUES and LOW-VALUES as if these constants will have a numeric meaning when moved to or compared with a numeric data item.
Unfortunately, this intuitive understanding conflicts with the definition given by COBOL. Worse yet, COBOL explicitly allows the combination of alphanumeric and numeric data in MOVE statements and relation conditions. Therefore, past RM/COBOL compilers have not diagnosed programming problems that may result. Modern versions of the RM/COBOL compiler will warn you when HIGH-VALUES or LOW-VALUES are moved to a numeric data item and the result is not well defined. The following paragraphs help clarify the actual meaning of HIGH-VALUES and LOW-VALUES.
HIGH-VALUES and LOW-VALUES are defined in COBOL as always being alphanumeric. This contrasts with the figurative constant ZEROES, which is numeric when associated with a numeric data item and alphanumeric when associated with a nonnumeric data item. Despite being figurative "constants", HIGH-VALUES and LOW-VALUES may have different values in different programs.
LOW-VALUES is defined as one or more of the characters with the lowest position in the program collating sequence. HIGH-VALUES is defined as one or more of the characters with the highest position in the program collating sequence. The program collating sequence may be specified by the PROGRAM COLLATING SEQUENCE clause in the OBJECT-COMPUTER paragraph using an alphabet-name defined in the SPECIAL-NAMES paragraph. For the default native collating sequence, LOW-VALUES has the value X"00" (a character code of all binary zeros) and HIGH-VALUES has the value X"FF" (a character code of all binary ones).
LOW-VALUES and HIGH-VALUES are extremely useful when sorting alphanumeric data according to the program collating sequence. The RM/COBOL compiler listing allocation map shows the values assigned to LOW-VALUES and HIGH-VALUES whenever any special-names are defined. If the program collating sequence is declared to be PCS where PCS is defined as:
ALPHABET PCS IS "0", 1 THRU 48, 59 THRU 256, "1" THRU "9"
then LOW-VALUES will be "0" and HIGH-VALUES will be "9" for that program. In this case, MOVE LOW-VALUES or MOVE HIGH-VALUES to a numeric data item is well defined in COBOL.
COBOL defines that an alphanumeric to numeric MOVE occurs "as if the sending operand were described as an unsigned numeric integer." Thus, MOVE "123" TO NUMERIC-ITEM is equivalent to MOVE 123 TO NUMERIC-ITEM and both moves are well defined in COBOL. However, moving LOW-VALUES (or HIGH-VALUES) TO NUMERIC-ITEM has undefined results when the program collating sequence is native or is any other collating sequence where HIGH-VALUES or LOW-VALUES do not correspond to a native digit character.
The result is undefined because COBOL does not specify the algorithm to convert a string of characters to a numeric value. For any one algorithm, the results are consistent even when the string does not contain digits. However, different algorithms used in different implementations of COBOL often yield different results for characters that are not digits.
COBOL attempts to define a language that is highly portable from one implementation to another, without limiting implementations by specifying algorithms, particularly with regard to incompatible data. It is unfortunate that COBOL does not define a numeric figurative constant for the lowest and highest numeric value.
For an unsigned integer data item, ZERO and ALL "9", respectively, are correct. However, for signed and noninteger data items, COBOL provides no generic low or high value constant (clearly, this "constant" would have different values depending on the numeric data item with which it was associated).
Relation conditions that specify the figurative constants LOW-VALUES or HIGH-VALUES suffer from a slightly different problem. Such relation conditions are defined in COBOL as if the numeric operand were moved to an alphanumeric data item and then this alphanumeric data item compared with the nonnumeric operand, LOW-VALUES or HIGH-VALUES, according to the collating sequence defined for the program.
If the numeric operand contains valid data, then moving it to an alphanumeric data item will result in a string of native digit characters. Any sign for the numeric data item is ignored and not moved. If the program uses the native collating sequence, then this intermediate alphanumeric item will always compare higher than LOW-VALUES and lower than HIGH-VALUES.