Michael Coughlan
Page 11
Rounded Result
342.736
PIC 999V99
342.73
342.74
342.734
PIC 999V99
342.73
342.73
342.534
PIC 999
342
343
342.464
PIC 999
342
342
5.958
PIC 9V99
5.95
5.96
12.821565
PIC 99V9(5)
12.82156
12.82157
The ON SIZE ERROR
A size error occurs when the computed result is too large or too small to fit into the receiving field. When the ON SIZE
ERROR phrase is used, it is followed by a block of COBOL statements that usually alert you that an error condition has occurred. For instance, in the following example, if FinalResult is too small to hold the result of all these multiplications, the ON SIZE ERROR activates and the alert message is displayed:
COMPUTE FinalResult = Num1 * Num2 * Num3 * Num4
ON SIZE ERROR DISPLAY "Alert: FinalResult too small to hold result"
END-COMPUTE
The scope of the statement block is delimited by the appropriate END delimiter (END-ADD, END-SUBTRACT,
END-MULTIPLY, END-DIVIDE, END-COMPUTE).
The ON SIZE ERROR acts like a specialized exception handler that comes into play if there is division by zero or if unexpected truncation occurs. When a computation is performed and decimal point alignment has occurred between the calculated result and the receiving data item, the result may be truncated on either the left side or the right. If the most significant digits are truncated, the size error activates. If there is truncation of the least significant digits, size error activation depends on whether the ROUNDED phrase is specified. If it is, then truncation of the least significant digits is ignored because using the ROUNDED phrase indicates that you know there will be truncation and have specified rounding to deal with it. Table 4-2 gives some ON SIZE ERROR examples.
62
Chapter 4 ■ proCedure division BasiCs
Table 4-2. ON SIZE ERROR Examples. Digits in the Actual Result column that will be truncated are not in bold Actual Result
Result Data item
Truncated Result
SIZE ERROR?
761.758
999V99
761.75
YES
8 is truncated on the right.
1761.78
999V99
761.78
YES
1 is truncated on the left.
374
999
374
NO
1761
999
761
YES
1 is truncated on the left.
326.475
999V99
326.47
YES
5 is truncated on the right.
326.475
999V99 ROUNDED
326.48
NO
5 is truncated on the right, but rounding is specified.
1326.475
999V99 ROUNDED
326.48
YES
1 is truncated on the left.
Nonconforming Arithmetic Verbs
When the common arithmetic verb template was introduced, I mentioned that there are forms of some verbs that do not conform to the template. This section gives the full metalanguage for COMPUTE, ADD, SUBTRACT, MULTIPLY, and DIVIDE and discusses in more detail the versions of these verbs that do not conform to the template.
The COMPUTE Verb
COMPUTE assigns the result of an arithmetic expression to a data item. The arithmetic expression to the right of the equal sign is evaluated, and the result is assigned to the data item(s) on the left of the equal sign. The arithmetic expression is evaluated according to the normal arithmetic rules. That is, the expression is normally evaluated from left to right, but bracketing and precedence rules (see Table 4-3) can change the order of evaluation.
Table 4-3. Precedence Rules
Precedence
Symbol
Meaning
1
**
Power
2
*
Multiply
/
Divide
3
+
Add
-
Subtract
■ Note unlike some other programming languages, CoBoL provides the ** expression symbol to represent raising to a power.
63
Chapter 4 ■ proCedure division BasiCs
COMPUTE is the COBOL verb most similar to assignment in other programming languages. For that reason, you
may be tempted to use it for plain assignments of data items to data items. COMPUTE should never be used for that purpose; in COBOL, you have the MOVE verb for that.
The familiarity of COMPUTE may also cause you to use it in preference to the other arithmetic verbs. There is no major objection to doing so, but knowledge of the other arithmetic verbs is required if you will be working with legacy systems.
Figure 4-4 shows the metalanguage for the COMPUTE verb.
Figure 4-4. COMPUTE metalanguage
COMPUTE Examples
Each example in this section is followed by a diagram that shows the value of the data items before and after COMPUTE
executes.
Let’s start with some literal values:
COMPUTE Result = 90 - 7 * 3 + 50 / 2
01 Result PIC 9(4) VALUE 3333.
Before
3333
After
0094
This is equivalent to
COMPUTE Result = 90 - (7 * 3) + (50 / 2)
01 Result PIC 9(4) VALUE 3333.
Before
3333
After
0094
Here’s another example:
COMPUTE Euro ROUNDED = Dollar / ExchangeRate
01 Euro PIC 9(5)V99 VALUE 3425.15.
01 Dollar PIC 9(5)V99 VALUE 1234.75.
01 ExchangeRate PIC 9V9(4) VALUE 1.3017.
Euro
Dollar
Exchange Rate
Before
3425.15
1234.75
1.3017
After
0948.57
1234.75
1.3017
64
Chapter 4 ■ proCedure division BasiCs
The ADD Verb
The ADD verb is used for addition. You might think COMPUTE could be used for that, and of course it can, but sometimes it can be simpler to use ADD. For instance, to increment a counter, you need COMPUTE ItemCount = ItemCount + 1, whereas you could just use ADD 1 TO ItemCount.
The metalanguage for the ADD verb is given in Figure 4-5.
Figure 4-5. ADD verb metalanguage
Notes
The ADD verb mostly conforms to the common template, but note the ellipsis after the first operand. This means you could have a statement like
ADD Num1, Num2, Num3 TO Num4 GIVING Result.
What are the semantics of this version of ADD? The items before TO are all added together, and then the result is applied to the operand or operands after TO.
Note also that in the GIVING version of the ADD verb, the word TO is optional (square brackets). This means you could have a statement like
ADD Num1, Num2, Num3 GIVING Result.
In this version, all the operands before GIVING are added together, and the result is placed in the
Result data item.
ADD Examples
Each example in this section is followed by a figure that shows the value of the data items before and after ADD
executes:
ADD Cash TO Total.
01 Cash PIC 9(3) VALUE 364.
01 Total PIC 9(4) VALUE 1000.
Cash
Total
Before
36
4
1000
After
364
1364
ADD Cash, 20 TO Total.
01 Cash PIC 9(3) VALUE 364.
01 Total PIC 9(4) VALUE 1000.
65
Chapter 4 ■ proCedure division BasiCs
Cash
Total
Before
364
1000
After
364
1384
ADD Cash, Checks TO Total.
01 Cash PIC 9(3) VALUE 364.
01 Total PIC 9(4) VALUE 1000.
01 Checks PIC (4) VALUE 1445.
Cash
Checks
Total
Before
364
1445
1000
After
364
1445
2809
The SUBTRACT Verb
The SUBTRACT verb is a specialized verb used for subtraction. It can be more convenient to use SUBTRACT to decrement a counter rather than COMPUTE. For instance, to decrement a counter you need COMPUTE ItemCount = ItemCount – 1, whereas you could just use SUBTRACT 1 FROM ItemCount.
The metalanguage for the SUBTRACT verb is given in Figure 4-6.
Figure 4-6. Metalanguage for the SUBTRACT verb
Notes
The SUBTRACT verb mostly conforms to the common template, but just as with ADD, there is an ellipsis after the first operand. This means you could have statements like these:
SUBTRACT Num1, Num2 FROM Num3 GIVING Result.
SUBTRACT Num1, Num2 FROM NumResult1, NumResult2.
In the first example, all the items before the word FROM are added together, the combined result is subtracted from num3, and the result is placed in the Result data item.
In the second example, all the items before the word FROM are added together. The combined result is subtracted from NumResult1, and the result is placed in NumResult1. The combined result is also subtracted from NumResult2, and the result of that calculation is placed in NumResult2.
66
Chapter 4 ■ proCedure division BasiCs
SUBTRACT Examples
Here are some examples of SUBTRACT:
SUBTRACT Num1, Num2 FROM Num3 GIVING Result.
01 Num1 PIC 9(4) VALUE 364.
01 Num2 PIC 9(4) VALUE 1000.
01 Num3 PIC 9(4) VALUE 5555.
01 Result PIC 9(4) VALUE 1445.
Num1
Num2
Num3
Result
Before
364
1000
5555
1445
After
364
1000
5555
4191
SUBTRACT Num1, Num2 FROM NumResult1, NumResult2.
01 Num1 PIC 9(4) VALUE 364.
01 Num2 PIC 9(4) VALUE 1000.
01 NumResult1 PIC 9(4) VALUE 5555.
01 NumResult2 PIC 9(4) VALUE 1445.
Num1
Num2
NumResult1
NumResult2
Before
364
1000
5555
1445
After
364
1000
4191
0081
SUBTRACT Tax, PRSI, Pension, Levy FROM GrossPay GIVING NetPay.
01 GrossPay PIC 9(4)V99 VALUE 6350.75.
01 Tax PIC 9(4)V99 VALUE 2333.25.
01 PRSI PIC 9(4)V99 VALUE 1085.45.
01 Pension PIC 9(4)V99 VALUE 1135.74.
01 Levy PIC 9(3)V99 VALUE 170.50.
01 NetPay PIC 9(4)V99 VALUE ZEROS.
GrossPay
Tax
PRSI
Pension
Levy
NetPay
Before
6350.75
2333.25
1085.45
1135.74
170.50
0000.00
After
6350.75
2333.25
1085.45
1135.74
170.50
1625.81
The MULTIPLY Verb
The MULTIPLY verb is one of the arithmetic verbs that fully conforms to the common template given in Figure 4-3.
The metalanguage for the MULTIPLY verb is given in Figure 4-7.
67
Chapter 4 ■ proCedure division BasiCs
Figure 4-7. Metalanguage for the MULTIPLY verb
MULTIPLY Examples
Here are some examples of MULTIPLY:
Multiply Fees BY Members GIVING TotalFees
DISPLAY "Alert: result to large for TotalFees"
01 Fees PIC 9(3)V99 VALUE 052.24
01 Members PIC 9(4) VALUE 1024.
01 TotalFees PIC 9(5)V99 VALUE ZEROS.
Fees
Members
TotalFees
Before
052.24
1024
00000.00
After
052.24
1024
53493.76
The DIVIDE Verb
The DIVIDE verb has two main formats. The metalanguage for the first format is given in Figure 4-8. This format is unremarkable in that it conforms to the common template. The metalanguage for the second format is given in Figure 4-9. This format does not conform to the common template, and it provides operations that cannot be done with COMPUTE. The second format of DIVIDE allows you to get the quotient and the remainder in one operation.
Figure 4-8. Metalanguage for format 1 of the DIVIDE verb
Figure 4-9. Metalanguage for format 2 of the DIVIDE verb
68
Chapter 4 ■ proCedure division BasiCs
DIVIDE Examples
Following are some DIVIDE examples; the third example uses the second format.
In this example, 15 is divided into Amount1, and the result is placed in Amount1; 15 is also divided into Amount2, and result is placed in Amount2. The results calculated are not integer values, so there is truncation of the digits to the left of the decimal point:
DIVIDE 15 INTO Amount1, Amount2.
01 Amount1 PIC 9(4) VALUE 2444.
01 Amount2 PIC 9(3) VALUE 354.
Amount1
Amount2
Before
2444
354
After
162
023
In this example, the calculated result is not an integer value, so there is truncation of the digits to the left of the decimal point. But because rounding is requested, the result is rounded to 272 (from 271.7826086956522):
DIVIDE Qty By Units GIVING Average ROUNDED.
01 Qty PIC 9(5) VALUE 31255.
01 Units PIC 9(3) VALUE 115.
01 Average PIC 9(4) VALUE ZEROS.
Qty
Units Average
Before
31255
115
0000
After
31255
115
0272
This example uses the second format of DIVIDE. It shows how you can use DIVIDE to get both the quotient and the remainder in one operation:
DIVIDE 215 BY 10 GIVING Quotient REMAINDER Rem.
01 Quotient PIC 999 VALUE ZEROS.
01 Rem PIC 9 VALUE ZEROS.
Quotient
Rem
Before
000
0
After
021
5
Let’s Write a Program
Listing 4-2 presents a very simple program that takes two single-digit numbers from the keyboard, multiplies them together, and then displays the result. This program uses only one of the three classic constructs of structured programming. These constructs are
• Sequence
• Selection
• Iteration
69
Chapter 4 ■ proCedure division BasiCs
In this program, execution starts in the PROCEDURE DIVISION para
graph CalculateResult and then continues
through the program statements one by one, in sequence, until STOP RUN is reached.
Obviously, a program like this has limited usefulness. To make it really useful, you need to be able to selectively execute program statements (selection) and specify that others are to be executed over and over again (iteration).
You revisit this program in the next two chapters when you are armed with the necessary selection and iteration constructs.
Listing 4-2. Example Program: ACCEPT, DISPLAY, and MULTIPLY
IDENTIFICATION DIVISION.
PROGRAM-ID. Listing4-2.
AUTHOR. Michael Coughlan.
*> Accepts two numbers from the user, multiplies them together
*> and then displays the result.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Num1 PIC 9 VALUE 5.
01 Num2 PIC 9 VALUE 4.
01 Result PIC 99 VALUE ZEROS.
PROCEDURE DIVISION.
CalculateResult.
DISPLAY "Enter a single digit number - " WITH NO ADVANCING
ACCEPT Num1
DISPLAY "Enter a single digit number - " WITH NO ADVANCING
ACCEPT Num2
MULTIPLY Num1 BY Num2 GIVING Result
DISPLAY "Result is = ", Result
STOP RUN.
Summary
In this chapter, you examined the operation of the arithmetic verbs COMPUTE, ADD, SUBTRACT, MULTIPLY, and DIVIDE.
The ACCEPT and DISPLAY verbs, which allow you to get input from the keyboard and send output to the screen, were also explored.
The final example program consisted of a sequence of statements that are executed one after another. This kind of program is of limited usefulness. To be truly useful, a program must incorporate iteration and selection. These control structures are explored in the next chapter, along with the jewel in COBOL’s crown: condition names.
70
Chapter 4 ■ proCedure division BasiCs
LaNGUaGe KNOWLeDGe eXerCISeS
sharpen up the 2B pencil you used to answer the questions in the last chapter, and fill in the after positions for data items that have a before entry:
01 Num1 PIC 99.
01 Num2 PIC 99.
01 Num3 PIC 99.
01 Num4 PIC 99.
Before Values
After Values