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.