Archives par mot-clé : COMPUTE

8.2 LES INSTRUCTIONS ARITHMETIQUES

Les instructions arithmétiques sont de 2 types:

  • les opérations simples :
    ADD
    SUBTRACT
    MULTIPLY
    DIVIDE
  • les opérations complexes :
    COMPUTE et ses opérateurs + – * / **

Ces instructions disposent d’options communes :

GIVING nom-de-donnée :
qui indique que le résultat de l’opération sera mémorisé dans nom-de-donnée.
ADD VAR1 VAR2 GIVING RESULTAT

ROUNDED :
après une opération le résultat tronque les décimales au-delà de ce qui
a été déclaré dans la PIC. Ainsi la quantité 234,478 sera de 234,4 si la
PIC de la variable résultat est de 999V9.
Avec ROUNDED, COBOL ajoute 5 au premier chiffre non significatif de droite pour réaliser l’arrondi à l’unité supérieure du chiffre le moins significatif si le premier chiffre non significatif de droite est >= 5.
Avec rounded notre exemple devient 234,5.

ON SIZE ERROR ordre impératif

Cette option permet de prévenir des incidents de calcul comme :
– la division par zéro
– les dépassements de capacité (pour rappel un numérique est limité à 18 chiffres)

exemple : DIVIDE A BY B ON SIZE ERROR MOVE ZERO TO B

!!!! Les calculs ne pourront se faire naturellement qu’avec des zones élémentaires numériques, il en ira de même pour les constantes. !!!!

L’ADDITION – ADD

Format n°1 :

    | nom-de-donnée-1      | | nom-de-donné-2       |
ADD |                                                         |     |                                                          |
    | littéral-numérique-1 | | littéral-numérique-2 |

    TO nom-de-donnée
[ ROUNDED].
     nom-de-donnée
-n [ ROUNDED].
   [ ON SIZE ERROR ordre-impératif
].

On ajoute nom-de-donnée-1 ou littéral-numérique-1 et nom-de-donnée-2 ou littéral-numérique-2 à la variable nom-de-donnée et le résultat peut être arrondi.

Exemple :

ADD 1000 QTE1 TO TOTAL ROUNDED ON SIZE ERROR MOVE 0 TO TOTAL

Ce qui signifie ajouter 1000 + QTE1 + TOTAL arrondir, transférer le résultat de l’opération dans TOTAL. En cas d’erreur mettre TOTAL à 0.

Format n° 2 :

    |nom-de-donnée-1| |nom-de-donné-2|     |nom-de-donné-n|
ADD |                                         |    |                                      | … |                                        |
    | littéral-1    | | littéral-2   |  | littéral-n   |

    GIVING nom-de-donnée
[ ROUNDED].
   [ ON SIZE ERROR ordre-impératif
].

Dans ce cas on ajoute nom-donnée-1 à nom-donnée-2 à….. nom-donnée-n le résultat est placé dans nom-de-donnée, éventuellement arrondi.

Exemple :
ADD TVA TOTHTVA GIVING TOTTVAC

Format n°3 :

ADD CORRESPONDING nom-de-groupe-1 TO nom-de-groupe2
[ ROUNDED ] [ ON SIZE ERROR ordre-imp. ]

Avec ce format, les zones élémentaires du groupe-1 sont additionnées aux données élémentaires du groupe-2 ayants des noms-données identiques, et les résultats sont placés dans les zones élémentaires du groupe-2.

L’abréviation COBOL de CORRESPONDING est CORR. Les clauses OCCURS et REDEFINES sont mal supportées.

Prenons par exemple un fichier paie mensuel d’enregistrement ENRMENS et le fichier ENRTOT.

De description :

01 ENRMENS.
   02 CODE-EMPLOYEE PIC 999.
   02 HEURE-P       PIC 999.
   02 SAL-BRUT      PIC 9(6).
01 ENRTOT.
   02 COD-EMPL      PIC 999.
   02 HEURE-P       PIC 999.
   02 SAL-BRUT      PIC 9(6).
   02 SAL-NET       PIC 9(6).

Le fait d’écrire ADD CORR ENRMENS TO ENRTOT, engendre les additions suivantes :

HEURE-P OF ENRTOT = HEURE-P OF ENRTOT + HEURE-P OF ENRMENS
SAL-BRUT OF ENRTOT = SAL-BRUT OF ENRTOT + SAL-BRUT OF ENRMENS

ADD identifier-1 TO identifier-2
         ROUNDED ON SIZE ERROR ordre-impératif-1
         NOT ON SIZE ERROR ordre impératif-2
END-ADD

ADD identifier-1 TO identifier-2
         GIVING identifier-3 ROUNDED
         ON SIZE ERROR ordre-impératif-1
         NOT ON SIZE ERROR ordre-impératif-2
END-ADD

Identifier-1 peut être une constante ou une variable numérique ou un ensemble des deux.
Les ordres impératifs 1 et 2 peuvent être constitués d’une ou de plusieurs instructions.
Avec l’option GIVING identifier-2 peut également être une constante numérique puisque le résultat est placé dans identifier-3.

LA SOUSTRACTION – SUBTRACT

Format 1 :

        |Identifier-1|
SUBTRACT|                                 |   FROM identifier-2 ROUNDED
        | littéral-1 |

        ON SIZE ERROR ordre-impératif-1

      NOT ON SIZE ERROR ordre-impératif-2

END-SUBTRACT

Format 2 :

        |Identifier-1|      |Identifier-2|
SUBTRACT|                                 |   FROM |            |
        | littéral-1 |      | littéral-2 |

      GIVING  identifier-3
 
    ROUNDED ON SIZE ERROR ordre-impératif-1

          NOT ON SIZE ERROR ordre-impératif-2

END-SUBTRACT

Format 3 :

SUBTRACT CORR identifier-1 FROM identifier-2 ROUNDED
ON SIZE ERROR ordre-impératif-1
NOT ON SIZE ERROR ordre-impératif-2
END-SUBTRACT

Remarques:
identifier-1 peut être une série de variables ou de constantes numériques.
Les options ROUNDED et ON SIZE ERROR ne sont pas obligatoires.
END-SUBTRACT ne s’applique que si les options SIZE ERROR sont utilisées.

Exemple :
SUBTRACT V1 V2 12 FROM TOTAL. (TOTAL = TOTAL – (V1 + V2 + 12))
SUBTRACT V1 V2 12 FROM TOTAL GIVING SOUSTOT.
(SOUSTOT = TOTAL – (V1 + V2 + 12))

Dans le 1er cas TOTAL doit être un numérique de travail, dans le 2ème cas SOUSTOT peut être un numérique d’édition car il n’intervient pas dans le calcul.

LA MULTIPLICATION – MULTIPLY

Format 1 :

        |Identifier-1|
MULTIPLY|                                 |   BY identifier-2 ROUNDED
        | littéral-1 |

        ON SIZE ERROR ordre-impératif-1

        NOT ON SIZE ERROR ordre-impératif-2

END-MULTIPLY

Format 2 :

         |Identifier-1|     |Identifier-2|
MULTIPLY |                                 |    BY |            |
         | littéral-1 |     | littéral-2 |

      GIVING  identifier-3
 
    ROUNDED ON SIZE ERROR ordre-impératif-1

          NOT ON SIZE ERROR ordre-impératif-2

END-MULTIPLY

Exemple :
MULTIPLY 12 BY V1.           ( V1 = V1 * 12)
MULTIPLY V1 BY V2 GIVING V3. ( V3 = V1 * V2)

LA DIVISION – DIVIDE

Format 1 :

       |Identifier-1|
DIVIDE |                                 |   INTO identifier-2 ROUNDED
       | littéral-1 |

        ON SIZE ERROR ordre-impératif-1

        NOT ON SIZE ERROR ordre-impératif-2

END-DIVIDE

Format 2 :

         |Identifier-1| |INTO| |Identifier-2|
DIVIDE   |                                 | |    | |            |
         | littéral-1 | | BY | | littéral-2 |

      GIVING  identifier-3
 
    ROUNDED ON SIZE ERROR ordre-impératif-1

          NOT ON SIZE ERROR ordre-impératif-2

END-DIVIDE

Format 3 :

         |Identifier-1| |INTO| |Identifier-2|
DIVIDE   |                                 | |    | |            |
         | littéral-1 | | BY | | littéral-2 |

      GIVING  identifier-3
      ROUNDED
REMAINDER identifier-4
 
    ON SIZE ERROR ordre-impératif-1

      NOT ON SIZE ERROR ordre-impératif-2

END-DIVIDE

Exemple :
DIVIDE 10 INTO V1. (V1 = V1 / 10)
DIVIDE V1 BY V2 GIVING V3. ( V3 = V1 / V2)
DIVIDE V1 BY V2 GIVING V3 REMAINDER RESTE.
(V3 = V1 / V2) et RESTE = V1 – (V2 * V3)

le tout en entier sans quoi il n’y a pas de reste

L’INSTRUCTION – COMPUTE

                        |expression-arithmétique|
COMPUTE  nom-item-1 =   |constant             |   
                        |nom-item               |

Les symboles arithmétiques valides sont :

+ pour l’addition
– pour la soustraction
* pour la multiplication
/ pour la division
** pour l’exposant

Un symbole arithmétique doit être précédé et suivi par au moins un espace.

Format :
COMPUTE identifier-1 ROUNDED = expression
ON SIZE ERROR ordre-impératif-1
NOT ON SIZE ERROR ordre-impératif-2
END-COMPUTE

L’expression : doit être composée de constantes et de variables numériques séparées par des opérateurs arithmétiques.

Les opérateurs sont : + – * / ** ( )

Avec + pour addition, – pour la soustraction, * pour la multiplication, le / pour la division et ** pour un exposant.

Exemple :
COMPUTE RESULTAT = A + (B – 3) * (G / 4) + ( E ** 2).

L’expression est analysée de la gauche vers la droite en tenant compte des priorités suivantes :
d’abord les exposants **, ensuite les * et / puis les + et -.
Il faut autant de ( gauches que de ) droites.

Exemple – COMPUTE

Voici des exemple de programme utilisant COMPUTE :

IDENTIFICATION DIVISION.
PROGRAM-ID.  COMPUTE.
AUTHOR.      LA COMMUNAUTE DU COBOL.

DATA DIVISION.
WORKING-STORAGE SECTION.

01  WS-AUXILIARES.
    05  VALEUR-1      PIC 9(009)         VALUE ZEROES. 
    05  VALEUR-2      PIC 9(009)         VALUE ZEROES. 
    05  VALEUR-3      PIC 9(009)         VALUE ZEROES. 
    05  VALEUR-4      PIC 9(009)V9(002)  VALUE ZEROES. 
    05  VALEUR-5      PIC S9(009)        VALUE ZEROES. 
    05  VENTES        PIC 9(009)         VALUE ZEROES. 
    05  QUANTITE      PIC 9(009)         VALUE ZEROES. 

PROCEDURE DIVISION.

001-INIT.

Exemple 1

    MOVE 10 TO QUANTITE
    MOVE 09 TO VALEUR-1
    COMPUTE VENTES  = QUANTITE * VALEUR-1 / 5	

    DISPLAY "QUANTITE     " QUANTITE  
    DISPLAY "VALEUR-1     " VALEUR-1  
    DISPLAY "VENTES       " VENTES  

* Resultat du test:

* QUANTITE     000000010
* VALEUR-1     000000009
* VENTES       000000018

Exemple 2

    MOVE 05 TO VALEUR-1
    DISPLAY "VALEUR-1 AVANT  " VALEUR-1
    COMPUTE VALEUR-1 = VALEUR-1 + 1  
    DISPLAY "VALEUR-1 APRÈS " VALEUR-1
	
* Resultat du test:

* VALEUR-1 AVANT  000000005
* VALEUR-1 APRÈS  000000006

Exemple 3

    MOVE 05 TO VALEUR-1
    MOVE 15 TO VALEUR-2
    COMPUTE VALEUR-3 = VALEUR-1 - VALEUR-2 
    DISPLAY "VALEUR-1        " VALEUR-1  
    DISPLAY "VALEUR-2        " VALEUR-2  
    DISPLAY "VALEUR-3        " VALEUR-3  

* Resultat du test:

* VALEUR-1        000000005
* VALEUR-2        000000015
* VALEUR-3        000000010

Exemple 4

    MOVE 05 TO VALEUR-1
    MOVE 15 TO VALEUR-2
    COMPUTE VALEUR-3 = VALEUR-1 * VALEUR-2
    DISPLAY "VALEUR-1        " VALEUR-1  
    DISPLAY "VALEUR-2        " VALEUR-2  
    DISPLAY "VALEUR-3        " VALEUR-3  

* Resultat du test:

* VALEUR-1        000000005
* VALEUR-2        000000015
* VALEUR-3        000000075

Exemple 5

    MOVE 05 TO VALEUR-1
    MOVE 15 TO VALEUR-2
    COMPUTE VALEUR-3 = VALEUR-1 + VALEUR-2 + 50	
    DISPLAY "VALEUR-1        " VALEUR-1  
    DISPLAY "VALEUR-2        " VALEUR-2  
    DISPLAY "VALEUR-3        " VALEUR-3  

* Resultat du test:

* VALEUR-1        000000005
* VALEUR-2        000000015
* VALEUR-3        000000070

Exemple 6

    MOVE 05 TO VALEUR-1
    DISPLAY "VALEUR-1 AVANT  " VALEUR-1
    COMPUTE VALEUR-1 = VALEUR-1 - 1  
    DISPLAY "VALEUR-1 APRES  " VALEUR-1

* Resultat du test:

* VALEUR-1 AVANT  000000005
* VALEUR-1 APRES  000000004

Exemple 7

    COMPUTE VALEUR-1 VALEUR-2 VALEUR-3 = 2 * 3	
    DISPLAY "VALEUR-1        " VALEUR-1  
    DISPLAY "VALEUR-2        " VALEUR-2  
    DISPLAY "VALEUR-3        " VALEUR-3  

* Resultat du test:

* VALEUR-1        000000006
* VALEUR-2        000000006
* VALEUR-3        000000006

Exemple 8

    COMPUTE VALEUR-1 = 33 - 2 * (5 + 8 / 2 - (4 * 6 - 20 * (9 - 8)))

* Resultat du test:

  33 - 2 * (5 + 8 / 2 - (4 * 6 - 20 * (9 - 8)))
= 33 - 2 * (5 + 8 / 2 - 4)
= 33 - 2 * (5 + 4 - 4)
= 33 - 2 * 5
= 33 - 10

* VALEUR-1        000000023

Exemple 9

    COMPUTE VALEUR-1 = 63 - 2 * (5 + (8 / 2 - 4 * 6 - 20 * (19 - 17)))

* Resultat du test:

= 63 - 2 * (5 + (8 / 2 - 4 * 6 - 20 * 2))
= 63 - 2 * (5 + (4 - 24 - 40))
= 63 - 2 * (5 + (-60))
= 63 - 2 * (-55)
= 63 + 110

* VALEUR-1        000000173

Exemple 10

    COMPUTE VALEUR-5 = -3 * (4 - 6) - 2 * (5 * (3 - 5 * (-7 + 5) - 3))

* Resultat du test:

= -3 * (-2) - 2 * (5 * (3 - 5 * (-2) - 3))
=  6 - 2 * (5 * (3 + 10 - 3))
=  6 - 2 * (5 * 10)
=  6 - 2 * 50
=  6 - 100
= -94

* VALEUR-5       -000000094

Exemple 11

    MOVE 05 TO VALEUR-1
    MOVE 15 TO VALEUR-2
    COMPUTE VALEUR-2 ROUNDED = VALEUR-1 / 5	
    DISPLAY "VALEUR-1        " VALEUR-1  
    DISPLAY "VALEUR-2        " VALEUR-2  

* Resultat du test:

* VALEUR-1 AVANT  000000005
* VALEUR-2 AVANT  000000015

* VALEUR-1 APRES  000000005
* VALEUR-2 APRES  000000001

Exemple 12

    MOVE 11 TO VALEUR-1
    MOVE 03 TO VALEUR-2
    COMPUTE VALEUR-4 ROUNDED = VALEUR-1 / VALEUR-2	
    DISPLAY "VALEUR-1        " VALEUR-1  
    DISPLAY "VALEUR-2        " VALEUR-2  
    DISPLAY "VALEUR-4        " VALEUR-4  

* Resultat du test:

* VALEUR-1        000000011
* VALEUR-2        000000003
* VALEUR-4        000000003.67 (3.66666666666)

Exemple 13

    MOVE 10 TO VALEUR-1
    MOVE 03 TO VALEUR-2
    COMPUTE VALEUR-4 ROUNDED = VALEUR-1 / VALEUR-2	
    DISPLAY "VALEUR-1        " VALEUR-1  
    DISPLAY "VALEUR-2        " VALEUR-2  
    DISPLAY "VALEUR-4        " VALEUR-4  

* Resultat du test:

* VALEUR-1        000000010
* VALEUR-2        000000003
* VALEUR-4        000000003.33 (3.33333333333)