Calculations
Doing calculations is basic to computer programming. COBOL provides all of
the calculation power that is needed for most business programming. It is
not the appropriate language to use if you want to do high power mathematics.
ADD:
The ADD statement has two purposes: the first is to do a simple calculation
that adds one or more numbers together and produces and answer, the second
is adding one number to another and storing the answer in the second number.
A freqeunt application of this is adding to accumulate a total. Only the
simple version is covered here, other clauses are available and will be
covered separately. First, we will look at the ADD to do a simple
calculation.
Format of simple calculation using the ADD statement:
ADD {literal-1 or identifier-1} ... literal-n or identifier-n
GIVING identifier-x [ROUNDED].
ADD{literal-1 or identifier-1}... TO literal-n or identifier-n
GIVING identifier-x [ROUNDED].
The ADD statement lets you add literals and/or identifiers (contents of
fields - can be defined in the File Section or the Working-Storage Section)
and store the answer in an identifer (usually defined in Working-Storage).
The word TO is optional - in versions of COBOL before COBOL '85 you could
not use TO and GIVING in the same ADD statement. The GIVING clauses points
to the place where the answer will be stored (identifier-x). When an ADD is
done, any previous value that is stored in identifier-x will be wiped out
and replaced with the result of the calculation. ROUNDED is optional. If
the clause ROUNDED is used, the answer will be rounded to fit the
identifier defined as the answer. If ROUNDED is not used, the answer will
be truncated to fit the identifier defined as the answer.
ADD Examples:
In these examples, assume that the following fields have been defined in the
FILE SECTION (on input records that are read) and in WORKING-STORAGE.
FILE SECTION.
FD INPUT-FILE...
01 INPUT-REC.
05 AMT1 PIC 99.
05 AMT2 PIC 999.
05 AMT3 PIC 9999.
05 AMT4 PIC 99V99.
05 AMT5 PIC 999V99.
05 AMT6 PIC 9999V99.
05 AMT7 PIC V99.
WORKING-STORAGE SECTION.
01 WORK-AREAS.
05 ANS-1-WS
PIC 9999 VALUE 0.
05 ANS-2-WS
PIC 99999 VALUE 0.
05 RSLT-1-WS
PIC 999V99 VALUE 0.
05 RSLT-2-WS
PIC 9999V99 VALUE 0.
05 RSLT-3-WS
PIC 99999V99 VALUE 0.
01 ACCUMULATORS.
05 TOTAL-1-ACC
PIC 99999 VALUE 0.
05 TOTAL-2-ACC
PIC 99999V99 VALUE 0.
ADD statements in the PROCEDURE DIVISION:
Using the TO............................................. |
Without the TO........................................... |
ADD AMT1 TO AMT2 GIVING ANS1-WS. |
ADD AMT1, AMT2 GIVING ANS1-WS.
Note: the comma is optional, can be used for clarity |
ADD 50 TO AMT1 GIVING ANS1-WS ROUNDED. |
ADD 50, AMT1 GIVING ANS1-WS ROUNDED. |
ADD AMT4 AMT5 TO AMT6 GIVING RSLT3-WS. |
ADD AMT4, AMT5, AMT6 GIVING RSLT3-WS. |
ADD 345.99 TO AMT5 GIVING RSLT2-WS. |
ADD 345.99, AMT5 GIVING RSLT2-WS. |
ADD AMT4 TO 1000 GIVING RSLT2-WS ROUNDED. |
ADD AMT4, 1000 GIVING RSLT2-WS ROUNDED. |
Format for increasing an amount or accumulating a total:
ADD {literal-1 or identifier-1}... TO identifier-x [ROUNDED].
ADD statements in the PROCEDURE DIVISION that use the ADD to increase an
amount or accumulate totals:
ADD 1 TO ANS1-WS.
ADD 5000 TO ANS2-WS.
ADD AMT6 TO RSLT3-WS ROUNDED.
ADD AMT5 TO RSLT2-WS.
In these examples, the answer stored in identifier-x keeps growing each time
the ADD is executed. Remember, it was the GIVING that wiped out the answer
in the previous examples and here there is no GIVING. When the optional
ROUNDED clause is used, the answer is rounded to fit the field where it is
stored, if the ROUNDED clause is not used, the answer is truncated to fit the
field. This format is frequently used when you are accumulating a total. In
this case the answer field would be stored under accumulators for clarity.
For example:
ADD 1 TO TOTAL-1-ACC.
ADD AMT6 TO TOTAL-2-ACC.
SUBTRACT:
Like the ADD, the SUBTRACT can be used to do a subtraction and arrive at an
answer (using the GIVING clause)or it can be used to decrease a specified
field and put the answer back in the field (using the FROM clause without
the GIVING clause). Again, the ROUNDED clause is optional and can be used
to round the answer to fit the field as opposed to the default which
truncates the answer to fit the field. Other options will be discussed
later.
FORMAT OF SIMPLE SUBTRACT CALCULATION:
SUBTRACT {literal-1 or identifier-1} ... FROM identifier-n
GIVING identifier-x [ROUNDED].
Examples:
SUBTRACT AMT1 FROM AMT3
GIVING ANS1-WS.
SUBTRACT AMT1, AMT2 FROM AMT3
GIVING ANS1-WS.
SUBTRACT AMT3 FROM 5000
GIVING ANS1-WS.
SUBTRACT 345.67 FROM AMT6
GIVING RSLT2-WS ROUNDED.
SUBTRACT AMT5 FROM AMT6
GIVING RSLT2-WS.
In the examples above, the SUBTRACT is executed and the result is stored in
the field specified by the GIVING clause. Any previous value in that answer
field is wiped out and replaced by the new answer. In the example where
AMT1, AMT2 are subtracted from AMT3, you can view it as AMT1 and AMT2 being
added together and the result subtracted from AMT3.
FORMAT OF DECREASING AN AMOUNT:
SUBTRACT {literal-1 or identifier-1}... FROM identifier-x [ROUNDED].
Examples:
SUBTRACT AMT1 FROM ANS1-WS.
SUBTRACT AMT2, AMT3 FROM ANS2-WS.
SUBTRACT 589.95 FROM RSLT1-WS ROUNDED.
SUBTRACT 200.12 FROM RSLT2-WS.
In these examples, the amounts are subtracted from the field or identifier
following the FROM clause and the result is stored in that field thereby
changing its value.
MULTIPLY:
The MULTIPLY statement again has two purposes, each with its own format. The
MULTIPLY statement can be used to multiply two literals or identifiers
together and store the results in an answer field (defined by the GIVING
clause) where the old answer is wiped out and replaced with the new answer.
In this case, if there are identifiers other than the answer involved in the
MULTIPLY they are not effected, their contents remains the same. The
MULTIPLY statement can also be used to multiply a literal or identifier by
an identifier and store the answer back in the identifier replacing the
value that used to be there. In this format, there is no GIVING clause.
Either format supports the optional ROUNDED clause that causes the answer to
be rounded rather than truncated. Other options are available and will be
discussed later. When you are doing multiplication, the size of the answer
is determined by the size of the fields used in the calculation.
Essentially if you add the number of whole number digits in each of the
fields in the calculation, the sum should be the number of whole number
digits that you setup in the answer field.
MULTIPLY using the giving clause:
MULTIPLY {identifier-1 or literal-1} BY {identifier-2 or literal-2}
GIVING identifer-x [ROUNDED].
The MULTIPLY statement multiplies either a literal or an identifier by
another literal or identifier and stores the answer in an identifier setup
to hold the answer. The fields involved in the calculation retain their
original values, the answer identifier receives the result of the calculation
as its value wiping out any previous value in the field.
Examples:
MULTIPLY AMT1 BY AMT2
GIVING ANS2-WS.
MULTIPLY AMT1 BY 12
GIVING ANS1-WS.
MULTIPLY AMT4 BY 10
GIVING RSLT1-WS.
MULTIPLY AMT3 BY AMT7
GIVING RSLT2-WS ROUNDED.
MULTIPLY USING THE BY CLAUSE:
MULTIPLY {identifier-1 or literal-1} BY identifier-x [ROUNDED].
The MULTIPLY statement multiplies an identifer or literal by an identifer
and stores the answer back in that identifier. The original value of the
answer identifier is lost.
Examples:
MULTIPLY AMT1 BY ANS1-WS.
MULTIPLY 10 BY ANS2-WS.
MULTIPLY 1.4 BY RSLT2-WS.
DIVIDE:
The DIVIDE has 5 different options that can be used because not only is
there the option to use or omit the GIVING clauses, but there is also the
option to use either BY or INTO in the DIVIDE itself.
DIVIDE FORMATS:
1. DIVIDE {literal-1 or identifier-1} INTO {literal-2 or identifier-2}
GIVING identifier-x [ROUNDED].
2. DIVIDE {literal-1 or identifier-1} INTO {literal-2 or identifier-2}
GIVING identifier-x [ROUNDED] REMAINDER indentifier-r.
3. DIVIDE {literal-1 or identifier-1} INTO identifier-2 [ROUNDED].
4. DIVIDE {literal-1 or identifier-1} BY {literal-2 or identifier-2}
GIVING identifier-x [ROUNDED].
5. DIVIDE {literal-1 or identifier-1} BY {literal-2 or identifier-2}
GIVING identifier-x [ROUNDED] REMAINDER indentifier-r.
In the first option, a literal or identifier is divided INTO another literal
or identifier and the answer is stored in an indentifier that was setup to
hold the answer. The answer can be ROUNDED to fit the field or the default
of truncation can be used. The following is an example:
COBOL Divide statement........................ |
Equivalent mathematical divide................ |
DIVIDE AMT1 INTO AMT3 GIVING RSLT1-WS. |
AMT3 divided by AMT1 equals RSLT1-WS
AMT3/AMT1=RSLT1-WS |
The second option is very similiar, but the REMAINDER that results from the
DIVIDE will be stored in a separate field that must be established in the
DATA DIVISION. For example:
DIVIDE AMT1 INTO AMT3
GIVING ANS2-WS
REMAINDER ANS1-WS.
DIVIDE AMT1 INTO AMT3.
The fourth option uses BY instead of INTO which means the DIVIDE works
differently as shown in the example below:
COBOL Divide statement........................ |
Equivalent mathematical divide................ |
DIVIDE AMT3 BY AMT1 GIVING RSLT1-WS. |
AMT3 divided by AMT1 equals RSLT1-WS
AMT3/AMT1=RSLT1-WS |
Notice the similiarities between the first option and this fourth option.
They result in the same answer, by one divides AMT1 INTO AMT3 and the other
divides AMT3 BY AMT1. Be careful when using these options to state the
DIVIDE the way you want it!
The fifth option is very similar to the second, both use the REMAINDER but
while the second uses INTO, the fifth uses BY. Note the example below which
accomplishes the same thing that is accomplished in the second example above.
DIVIDE AMT3 BY AMT1
GIVING ANS2-WS REMAINDER ANS1-WS.