Compaq COBOL
User Manual


Previous Contents Index

2.7.4.1 ROUNDED with REMAINDER

The remainder computation uses an intermediate field that is truncated, rather than rounded, when you use the DIVIDE statement with both the ROUNDED and REMAINDER options.

2.7.5 Using the SIZE ERROR Phrase

The SIZE ERROR phrase detects the loss of high-order nonzero digits in the results of Compaq COBOL arithmetic operations. It does this by checking the absolute value of an arithmetic result against the PICTURE character-string of each resultant identifier. For example, if the absolute value of the result is 100.05, and the PICTURE character-string of the resultant identifier is 99V99, the SIZE ERROR phrase detects that the high-order digit, 1, will be lost, and the size error condition will be raised.

You can use the phrase in any Compaq COBOL arithmetic statement.

When the execution of a statement with no ON SIZE ERROR phrase results in a size error, and native arithmetic is used, the values of all resultant identifiers are undefined. When standard arithmetic is used, or when the same statement includes an ON SIZE ERROR phrase, receiving items for which the size error exists are left unaltered; the result is stored in those receiving items for which no size error exists. The ON SIZE ERROR imperative phrase is then executed.

If the statement contains both ROUNDED and SIZE ERROR phrases, the result is rounded before a size error check is made.

The SIZE ERROR phrase cannot be used with numeric MOVE statements. Thus, if a program moves a numeric quantity to a smaller numeric item, it can lose high-order digits. For example, consider the following move of an item to a smaller item:


01 AMOUNT-A PIC S9(8)V99. 
01 AMOUNT-B PIC S9(4)V99. 
       . 
       . 
       . 
       MOVE AMOUNT-A TO AMOUNT-B. 

This MOVE operation always loses four of AMOUNT-A's high-order digits. The statement can be tailored in one of three ways, as shown in the following example, to determine whether these digits are zero or nonzero:


1.  IF AMOUNT-A NOT > 9999.99 
       MOVE AMOUNT-A TO AMOUNT-B 
       ELSE ... 
2.  ADD ZERO AMOUNT-A GIVING AMOUNT-B 
       ON SIZE ERROR ... 
3.  COMPUTE AMOUNT-B = AMOUNT-A 
       ON SIZE ERROR ... 

All three alternatives allow the MOVE operation to occur only if AMOUNT-A loses no significant digits. If the value in AMOUNT-A is too large, all three avoid altering AMOUNT-B and take the alternate execution path.

You can also use a NOT ON SIZE ERROR phrase to branch to, or perform, sections of code only when no size error occurs.

2.7.6 Using the GIVING Phrase

The GIVING phrase moves the intermediate result of an arithmetic operation to a receiving item. The phrase acts exactly like a MOVE statement in which the intermediate result serves as the sending item, and the data item following the word GIVING serves as the receiving item. When a statement contains a GIVING phrase, you can have a numeric-edited receiving item.

The receiving item can also have the ROUNDED phrase. If the receiving item is also numeric-edited, rounding takes place before the editing.

The GIVING phrase can be used with the ADD, SUBTRACT, MULTIPLY, and DIVIDE statements. For example:


ADD A,B GIVING C. 

2.7.7 Multiple Operands in ADD and SUBTRACT Statements

Both the ADD and SUBTRACT statements can contain a series of operands preceding the word TO, FROM, or GIVING.

If there are multiple operands in either of these statements, the operands are added together. The intermediate result of that operation becomes a single operand to be added to or subtracted from the receiving item. In the following examples, TEMP is an intermediate result item:
1. Statement: ADD A,B,C,D, TO E,F,G,H.
  Equivalent coding: ADD A, B, GIVING TEMP.
ADD TEMP, C, GIVING TEMP.
ADD TEMP, D, GIVING TEMP.
ADD TEMP, E, GIVING E.
ADD TEMP, F, GIVING F.
ADD TEMP, G, GIVING G.
ADD TEMP, H, GIVING H.
2. Statement: SUBTRACT A, B, C, FROM D.
  Equivalent coding: ADD A, B, GIVING TEMP.
ADD TEMP, C, GIVING TEMP.
SUBTRACT TEMP FROM D, GIVING D.
3. Statement: ADD A,B,C,D, GIVING E.
  Equivalent coding: ADD A,B, GIVING TEMP.
ADD TEMP, C, GIVING TEMP.
ADD TEMP, D, GIVING E.

As in all Compaq COBOL statements, the commas in these statements are optional.

2.7.8 Common Errors in Arithmetic Statements

Programmers most commonly make the following errors when using arithmetic statements:


Chapter 3
Handling Nonnumeric Data

Nonnumeric data in Compaq COBOL is evaluated with respect to a specified collating sequence of the operands.

Information to be found in this chapter:

3.1 Storage of Nonnumeric Data

COBOL programs hold their data in items whose sizes are described in their source programs. The size of these items is thus fixed during compilation for the lifespan of the resulting object program.

Items in a COBOL program belong to any of the following three data classes:

The data description of an item specifies which class that item belongs to.

Classes are further subdivided into categories. Alphanumeric items can be numeric edited, alphanumeric edited, or alphanumeric. Every elementary item, except for an index data item, belongs to one of the classes and its categories. The class of a group item is treated as alphanumeric regardless of the classes of subordinate elementary items.

If the data description of an alphanumeric item specifies that certain editing operations be performed on any value that is moved into it, that item is called an alphanumeric edited item.

As you read this chapter, keep in mind the distinction between the class or category of a data item and the actual value that the item contains.

Sometimes the text refers to alphabetic, alphanumeric, and alphanumeric edited data items as nonnumeric data items to distinguish them from items that are specifically numeric.

Regardless of the class of an item, it is usually possible at run time to store an invalid value in the item. Thus, nonnumeric ASCII characters can be placed in an item described as numeric, and an alphabetic item can be loaded with nonalphabetic characters. Invalid values can cause errors in output or run-time errors.

3.2 Data Organization

A Compaq COBOL record consists of a set of data description entries that describe record characteristics; it must have an 01 or 77 level number. A data description entry can be either a group item or an elementary item.

All of the records used by Compaq COBOL programs (except for certain registers and switches) must be described in the source program's Data Division. The compiler allocates memory space for these items (except for Linkage Section items) and fixes their size at compilation time.

The following sections explain how the compiler sets up storage for group and elementary data items.

3.2.1 Group Items

A group item is a data item that is followed by one or more elementary items or other group items, all of which have higher-valued level numbers than the group to which they are subordinate.

The size of a group item is the sum of the sizes of its subordinate elementary items. The compiler considers all group items to be alphanumeric DISPLAY items regardless of the class and usage of their subordinate elementary items.

3.2.2 Elementary Items

An elementary item is a data item that has no subordinate data item.

The size of an elementary item is determined by the number of symbols that represent character positions contained in the PICTURE character-string. For example, consider this record description:


01 TRANREC. 
   03 FIELD-1 PIC X(7). 
   03 FIELD-2 PIC S9(5)V99. 

Both elementary items require seven bytes of memory; however, item FIELD-1 contains seven alphanumeric characters while item FIELD-2 contains seven decimal digits, an operational sign, and an implied decimal point. Operations on such items are independent of the mapping of the item into memory words (32-bit words that hold four 8-bit bytes). An item can begin in the leftmost or rightmost byte of a word with no effect on the function of any operation that refers to that item. (However, the position of items in memory can have an effect on run-time performance.)

In effect, the compiler sees memory as a continuous array of bytes, not words. This becomes particularly important when you are defining a table using the OCCURS clause (see Chapter 4).

In Compaq COBOL, all records, and elementary items with level 01 or 77, begin at an address that is a multiple of 8 bytes (a quadword boundary). By default, the Compaq COBOL compiler will locate a subordinate data item at the next unassigned byte location.

See Chapter 16, Chapter 15, and the SYNCHRONIZED clause in the Compaq COBOL Reference Manual for a complete discussion of alignment.

3.3 Special Characters

Compaq COBOL allows you to handle any of the 128 characters of the ASCII character set as alphanumeric data, even though many of the characters are control characters, which usually direct input/output devices. Generally, alphanumeric data manipulations attach no meaning to the 8th bit of an 8-bit byte. Thus, you can move and compare these control characters in the same manner as alphabetic and numeric characters.

Note

Some control characters have 0 in the high-order bit and are part of the ASCII character set, while others have 1 in the high order bit and are not part of the ASCII character set.

Although the object program can manipulate all ASCII characters, certain control characters cannot appear in nonnumeric literals since the compiler uses them to delimit the source text.

You can place special characters into items of the object program by defining symbolic characters in the SPECIAL-NAMES paragraph or by using the EXTERNAL clause. See the Compaq COBOL Reference Manual for information on these two topics.

The ASCII character set listed in the Compaq COBOL Reference Manual indicates the decimal value for any ASCII character.

3.4 Testing Nonnumeric Items

The following sections describe the relation and class tests as they apply to nonnumeric items.

3.4.1 Relation Tests of Nonnumeric Items

An IF statement with a relation condition can compare the value in a nonnumeric data item with another value and use the result to alter the flow of control in the program.

An IF statement with a relation condition compares two operands. Either of these operands can be an identifier or a literal, but they cannot both be literals. If the stated relation exists between the two operands, the relation condition is true.

When coding a relational operator, leave a space before and after each reserved word. When the reserved word NOT is present, the compiler considers it and the next key word or relational character to be a single relational operator defining the comparison. Table 3-1 shows the meanings of the relational operators.

Table 3-1 Relational Operator Descriptions
Operator Description
IS [NOT] GREATER THAN
IS [NOT] >
The first operand is greater than (or not greater than) the second operand.
IS [NOT] LESS THAN
IS [NOT] <
The first operand is less than (or not less than) the second operand.
IS [NOT] EQUAL TO
IS [NOT] =
The first operand is equal to (or not equal to) the second operand.
IS GREATER THAN OR
EQUAL TO
IS >=
The first operand is greater than or equal to the second operand.
IS LESS THAN OR EQUAL TO
IS <=
The first operand is less than or equal to the second operand.

3.4.1.1 Classes of Data

Compaq COBOL allows comparison of both numeric class operands and nonnumeric class operands; however, it handles each class of data differently. For example, it allows a comparison of two numeric operands regardless of the formats specified in their respective USAGE clauses, but it requires that all other comparisons (including comparisons of any group items) be between operands with the same usage. It compares numeric class operands with respect to their algebraic values and nonnumeric (or numeric and nonnumeric) class operands with respect to a specified collating sequence. (See Section 2.5.1 for numeric comparisons.)

If only one of the operands is numeric, it must be an integer data item or an integer literal, and it must be DISPLAY usage. In these cases, the manner in which the compiler handles numeric operands depends on the nonnumeric operand, as follows:

The compiler does not accept a comparison between a noninteger numeric operand and a nonnumeric operand. If you try to compare these two items, you receive a diagnostic message at compile time.

3.4.1.2 Comparison Operations

If the two operands are acceptable, the compiler compares them character by character. The compiler starts at the first byte and compares the corresponding bytes until it either encounters a pair of unequal bytes or reaches the last byte of the longer operand.

If the compiler encounters a pair of unequal characters, it considers their relative position in the collating sequence. The operand with the character that is positioned higher in the collating sequence is the greater operand.

If the operands have different lengths, the comparison proceeds as though the shorter operand were extended on the right by sufficient ASCII spaces (decimal 32) to make both operands the same length.

If all character pairs are equal, the operands are equal.

3.4.2 Class Tests for Nonnumeric Items

An IF statement with a class condition tests the value in a nonnumeric data item (USAGE DISPLAY only) to determine whether it contains numeric, alphabetic, or user-defined data and uses the result to alter the flow of control in the program. For example:


IF ITEM-1 IS NUMERIC... 
IF ITEM-2 IS ALPHABETIC... 
IF ITEM-3 IS NOT NUMERIC... 

If the data item consists entirely of the ASCII characters 0 to 9, with or without the operational sign, the class condition is NUMERIC. If the item consists entirely of the ASCII characters A to Z (upper- or lowercase) and spaces, the class condition is ALPHABETIC.

The ALPHABETIC-LOWER test is true if the operand contains any combination of the lowercase alphabetic characters a to z, and the space. Otherwise the test is false.

The ALPHABETIC-UPPER test is true if the operand contains any combination of the uppercase alphabetical characters A to Z, and the space. Otherwise, the test is false.

You can also perform a class test on a data item that you define with the CLASS clause of the SPECIAL-NAMES paragraph.

A class test is true if the operand consists entirely of the characters listed in the definition of the CLASS-NAME in the SPECIAL-NAMES paragraph. Otherwise, the test is false.

When the reserved word NOT is present, the compiler considers it and the next key word as one class condition defining the class test to be executed. For example, NOT NUMERIC determines if an operand contains at least one nonnumeric character.

If the item being tested is described as a numeric data item, it can only be tested as NUMERIC or NOT NUMERIC. The NUMERIC test cannot examine either of the following:

For further information on using class conditions with numeric items, refer to the Compaq COBOL Reference Manual.

3.5 Data Movement

Three Compaq COBOL statements (MOVE, STRING, and UNSTRING) perform most of the data movement operations required by business-oriented programs. The MOVE statement simply moves data from one item to another. The STRING statement concatenates a series of sending items into a single receiving item. The UNSTRING statement disperses a single sending item into multiple receiving items. Section 3.6 describes the MOVE statement. Chapter 5 describes STRING and UNSTRING.

The MOVE statement handles most data movement operations on character strings. However, it is limited in its ability to handle multiple items. For example, it cannot, by itself, concatenate a series of sending items into a single receiving item or disperse a single sending item into several receiving items.

Two MOVE statements will, however, bring the contents of two items together into a third (receiving) item if the receiving item has been subdivided with subordinate elementary items that match the two sending items in size. If other items are to be concatenated into the third item, and they differ in size from the first two items, then the receiving item requires additional subdivisions (through redefinition).

Example 3-1 demonstrates item concatenation using two MOVE statements.

Example 3-1 Item Concatenation Using Two MOVE Statements

01  SEND-1        PIC X(5) VALUE "FIRST". 
01  SEND-2        PIC X(6) VALUE "SECOND". 
01  RECEIVE-GROUP. 
    05  REC-1     PIC X(5). 
    05  REC-2     PIC X(6). 
PROCEDURE DIVISION. 
A00-BEGIN. 
    MOVE SEND-1 TO REC-1. 
    MOVE SEND-2 TO REC-2. 
    DISPLAY RECEIVE-GROUP. 
    STOP RUN. 

The result of the concatenation follows:


FIRSTSECOND 

Two MOVE statements can also disperse the contents of one sending item to several receiving items. The first MOVE statement moves the leftmost end of the sending item to a receiving item; then the second MOVE statement moves the rightmost end of the sending item to another receiving item. (The second receiving item must first be described with the JUSTIFIED clause.) Characters from the middle of the sending item cannot easily be moved to any receiving item without extensive redefinitions of the sending item or a reference modification loop (as with concatenation).

The STRING and UNSTRING statements handle concatenation and dispersion more easily than compound moves. Reference modification handles substring operations more easily than compound moves, STRING, or UNSTRING.


Previous Next Contents Index