Professional Documents
Culture Documents
When performing data validation on zoned decimal numeric fields in COBOL, always
check for NUMERIC. Never rely upon IFs and 88s alone! This article will demonstrate
why.
I love 88s (condition names.) I often tell my students that I find them to be one of the
nicest features in COBOL. But IF statements, with or without 88s, when performed on
zoned decimal numeric fields, disregard the sign bits of all but the last digit.
Consequently, it is possible to have a non-numeric character, such as any letter of the
alphabet, in a supposed numeric field, and that field be treated as a number. IFs and 88s
won’t catch the error. However, at least to my knowledge, COBOL’s check for
NUMERIC cannot be fooled. Consider the following example
DATA DIVISION.
WORKING-STORAGE SECTION.
01 MISC.
05 INPUT-FLD-AS-X PIC X(5).
05 INPUT-FLD-AS-9 REDEFINES INPUT-FLD-AS-X PIC 9(3)V99.
88 VALID-VALUES VALUE 100 THRU 199.99.
05 OUTPUT-FLD-AS-Z PIC ZZ9.99.
The reason for this is that C’13E79’ is equivalent to X’F1F3C5F7F9’ and when
COBOL’s IF looks at a zoned decimal field, it ignores the zone bits (X’F’ and X’C’) in
all but the rightmost byte. Indeed, the COBOL compiler will generate a machine level
PACK instruction for the purpose of the compare (since zoned decimal instructions do
not exist at the machine level) and this value packs to X’13579F’, which is a valid packed
decimal numeric field.
So you should never rely upon a range check alone (with or without an 88.) The data
could be properly checked as follows: IF INPUT-FLD-AS-9 IS NUMERIC AND
VALID-VALUES
Source Code:
INPUT IS 09H7F
NOT NUMERIC
NOT VALID VALUE
LESS THAN 100
98.76
INPUT IS 12345
NUMERIC
VALID VALUE
BETWEEN 100 AND 199.99
123.45
INPUT IS 13E79
NOT NUMERIC
VALID VALUE
BETWEEN 100 AND 199.99
135.79
INPUT IS 2C45F
NOT NUMERIC
NOT VALID VALUE
GREATER THAN 199.99