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.

The ADD statement has two purposes: the first is to do a simple calculation that adds one or more numbers together and produces an answer, the second is adding one number to another and storing the answer in the second number. A frequent 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. To illustrate, I will use the WORKING-STORAGE SECTION from the program ADDDA4.CBL.

WORKING-STORAGE SECTION. 01 INPUT-AREA. 05 GET-ACCEPT-ANS PIC X VALUE SPACES. 05 FIRST-NUMBER PIC 999V99 VALUE 0. 05 SECOND-NUMBER PIC 999V99 VALUE 0. 01 WORK-AREA. 05 ADD-ANS-WS PIC 9999V99 VALUE 0. 05 FINAL-ANS-WS PIC 9999V99 VALUE 0. 01 OUTPUT-AREA. 05 ADD-ANS-OUT PIC Z,ZZ9.99. 05 FINAL-ANS-OUT PIC Z,ZZ9.99.Sample basic ADD statements (Note that these would be located in a paragraph in the PROCEDURE DIVISION):

ADD FIRST-NUMBER TO SECOND-NUMBER GIVING ADD-ANS-WS. ADD FIRST-NUMBER SECOND-NUMBER GIVING ADD-ANS-WS. ADD FIRST-NUMBER, SECOND-NUMBER GIVING ADD-ANS-WS. ADD 12 TO FIRST-NUMBER GIVING ADD-ANS-WS. ADD 100, FIRST-NUMBER, SECOND-NUMBER GIVING ADD-ANS-WS.The ADD statement can also be used to add the contents of one field to another or add a literal to a field. Note that you cannot add to a literal, only to a defined field (identifier).

ADD 50 TO FIRST-NUMBER. ADD FIRST-NUMBER TO SECOND-NUMBER.In the first example, since there is no GIVING clause in this statement, FIRST-NUMBER would be increased by 50. The original value in FIRST-NUMBER would be lost. In the second example SECOND-NUMBER would increase by the contents of FIRST-NUMBER and the original value in SECOND-NUMBER would be lost.

You can also round the answer by using the ROUNDED CLAUSE. For example, this would be necessary if you were adding two decimal numbers and storing the answer as a whole number.

WORKING-STORAGE SECTION. 01 INPUT-AREA. 05 GET-ACCEPT-ANS PIC X VALUE SPACES. 05 FIRST-NUMBER PIC 999V99 VALUE 0. 05 SECOND-NUMBER PIC 999V99 VALUE 0. 01 WORK-AREA. 05 ADD-ANS-WHOLE-WS PIC 9999 VALUE 0.

In the PROCEDURE DIVISION:

ADD FIRST-NUMBER TO SECOND-NUMBER GIVING ADD-ANS-WHOLE-WS ROUNDED.

In this example the numbers would be added together and the decimals would be lost when the answer was stored. If the calculation did not have ROUNDED, the decimals would be truncated. With the ROUNDED clause the answer would be ROUNDED following the standard rules of rounding. For example: assume that FIRST-NUMBER is 12.75 and second number is 3.07. When they are added together I get 15.82. Since I cannot store the .82, the number will be truncated if there is no ROUNDED clause and you will see 15. If there is a rounded clause, the number will be ROUNDED and you will see 16.

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 (actual number) 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.

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.

WORKING-STORAGE SECTION. 01 INPUT-AREA. 05 GET-ACCEPT-ANS PIC X VALUE SPACES. 05 FIRST-NUMBER PIC 999V99 VALUE 0. 05 SECOND-NUMBER PIC 999V99 VALUE 0. 01 WORK-AREA. 05 ANS-WS PIC 9999V99 VALUE 0. 05 FINAL-ANS-WS PIC 9999V99 VALUE 0. 01 OUTPUT-AREA. 05 ANS-OUT PIC Z,ZZ9.99. 05 FINAL-ANS-OUT PIC Z,ZZ9.99.Examples of the subtract statement:

SUBTRACT FIRST-NUMBER FROM SECOND-NUMBER GIVING ANS-WS. SUBTRACT 10 FROM SECOND-NUMBER GIVING ANS-WS. SUBTRACT FIRST-NUMBER FROM 100 GIVING ANS-WS.If you do not use the giving clause, then the answer is stored in the field after the FROM. Note that the field after the from must be an identifier/field name, it cannot be a literal. In other words you have to store it in something that has been defined in memory.

SUBTRACT 10 FROM SECOND-NUMBER. SUBTRACT FIRST-NUMBER FROM SECOND-NUMBER.In both examples, SECOND-NUMBER would be decreased from its original value.

You can also use rounded with the subtract statement. Assume that WHOLE-ANS-WS has a PIC 9999. Without the ROUNDED clause, the results would be truncated to fit the field. With the ROUNDED clause, the results will be rounded using the normal rules for rounding.

SUBTRACT FIRST-NUMBER FROM SECOND-NUMBER GIVING WHOLE-ANS-WS ROUNDED.

SUBTRACT {literal-1 or identifier-1} ... FROM identifier-n GIVING identifier-x [ROUNDED].NEGATIVE NUMBERS: Note that we have not dealt with negative numbers yet, you must test these subtractions with that in mind. In other words, you should use numbers so the answers will always be positive.

Examples of the multiply statement:

MULTIPLY FIRST-NUMBER BY SECOND-NUMBER GIVING ANS-WS. MULTIPLY 12 BY SECOND-NUMBER GIVING ANS-WS. MULTIPLY FIRST-NUMBER BY 12 GIVING ANS-WS. MULTIPLY FIRST-NUMBER BY SECOND-NUMBER GIVING WHOLE-ANS-WS ROUNDED.Note that you have to figure out the size of the answer field a little differently when you are doing a multiply. If you are multiplying 2 digits by 3 digits, you need a 5 digit answer (for example: 90 times 900 = 81000). If you are multiplying 3 digits by 4 digits, you need a 7 digit answer. In other words add up the digits being multiplied and that is the size of the answer. Try it!

If you do not use the GIVING clause, the answer gets stored in the field after the B. Note that you must have an identifier after the BY, not a literal when you do not have the GIVING clause.

MULTIPLY FIRST-NUMBER BY SECOND-NUMBER.In this example, the results will be stored in SECOND-NUMBER, wiping out the previous data that was stored there!

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.

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 of the DIVIDE with the INTO:

DIVIDE 10 INTO FIRST-NUMBER GIVING ANS-WS. DIVIDE FIRST-NUMBER INTO SECOND-NUMBER GIVING ANS-WS. DIVIDE FIRST-NUMBER INTO SECOND-NUMBER GIVING WHOLE-ANS-WS ROUNDED.In the first example, 10 is divided into FIRST-NUMBER and the result is put into ANS-WS. IF FIRST-NUMBER is 50, then 10 is divided into 50 and the result of 5 is put into ANS-WS. In the second and third examples the contents of FIRST-NUMBER is divided into the contents of SECOND-NUMBER and the results are put into the identifier after the GIVING. In the third example, the answer is rounded before it is stored in WHOLE-ANS-WS.

Examples of the DIVIDE with the BY:

DIVIDE FIRST-NUMBER BY 10 GIVING ANS-WS. DIVIDE SECOND-NUMBER BY FIRST-NUMBER GIVING ANS-WS. DIVIDE SECOND-NUMBER BY FIRST-NUMBER GIVING WHOLE-ANS-WS ROUNDED.I did the same mathematical problems in these 3 examples as I did in the original examples. Looking at the first example, if FIRST-NUMBER contains a 50 then 50 will be divided by 10 and the result of 5 will be put into ANS-WS.

Note that only the INTO can be used if there is no GIVING clause.

DIVIDE 10 INTO FIRST-NUMBER. DIVIDE FIRST-NUMBER INTO SECOND-NUMBER. DIVIDE FIRST-NUMBER INTO SECOND-NUMBER ROUNDED.In all of these examples, the contents of the identifier after the INTO is changed and the previous content is wiped out.

The DIVIDE also allows the programmer to store the remainder. Note that you cannot use ROUNDED when you are storing the remainder. THis can be done with either the BY or INTO. Assume in these examples that I have defined a field in working storage called REM-WS.

DIVIDE 10 INTO FIRST-NUMBER GIVING ANS-WS REMAINDER REM-WS. DIVIDE FIRST-NUMBER INTO SECOND-NUMBER GIVING ANS-WS REMAINDER REM-WS. DIVIDE FIRST-NUMBER BY 10 GIVING ANS-WS REMAINDER REM-WS. DIVIDE SECOND-NUMBER BY FIRST-NUMBER GIVING ANS-WS REMAINDER REM-WS.

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.