IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Pascal Discussion :

Résultat incorrect d'une somme


Sujet :

Pascal

  1. #1
    Membre à l'essai
    Homme Profil pro
    Etudiant
    Inscrit en
    Décembre 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Décembre 2013
    Messages : 14
    Points : 14
    Points
    14
    Par défaut Résultat incorrect d'une somme
    Bonjour,
    Pourquoi ce programme ne marche-t-il pas avec ces valeurs :
    s= 5000 k=2000 j=24
    et comment résoudre le problème ?
    Merci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    program e;
    uses wincrt;
    var i,j,k,s:integer;
    begin
     write('Entrer une somme: ');
     readln(s);
     write('Entrer somme a ajouter chaque année puis nombre d''année: ');
     readln(k,j);
     for i:=1 to j do
     s:=s+k;
     writeln('La somme sera de : ',s);
     readln;
    end.

  2. #2
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Bonjour ! 24 fois 2000 plus 5000 égale 53000. Apparemment tu utilises un vieux compilateur, pour lequel le type integer est une variable de 16 bits, dont la valeur est comprise entre -32768 et 32767.

    La solution est de changer le type de la variable. Il faut consulter l'aide de ton compilateur à la rubrique "Data types" (types de données).
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  3. #3
    ALT
    ALT est déconnecté
    Membre émérite
    Avatar de ALT
    Homme Profil pro
    Retraité
    Inscrit en
    Octobre 2002
    Messages
    1 234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 234
    Points : 2 338
    Points
    2 338
    Par défaut
    Je confirme !
    En l'absence de précision ("ça ne marche pas", on fait difficilement plus vague !), c'est l'explication la plus vraisemblable. Et la plus évidente !
    « Un peuple qui est prêt à sacrifier un peu de liberté contre un peu de sécurité, ne mérite ni l'une, ni l'autre, et finira par perdre les deux. »
    Attribué indistinctement à :
    Thomas Jefferson
    Benjamin Franklin
    Albert Einstein !

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 23
    Points : 22
    Points
    22
    Par défaut
    si tu ne dois pas changer de type utilise une condition ou une fonction qui teste si la valeur ne depasse pas

  5. #5
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par lagareg Voir le message
    si tu ne dois pas changer de type utilise une condition ou une fonction qui teste si la valeur ne depasse pas
    C'est intéressant. Quelque chose comme ça, alors ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    program int16;
     
    {$IFDEF VPASCAL}
      {&PMTYPE VIO}
      {&USE32-}
    {$ENDIF}
     
    var
      somme: integer;
      i: integer;
     
    begin
      WriteLn(SizeOf(somme)); // 2 (octets)
     
      somme := 5000;
      for i := 1 to 24 do
        if somme + 2000 <= High(integer) then
        begin
          somme := somme + 2000;
          WriteLn(somme);
        end else
        begin
          WriteLn('Erreur');
          break;
        end;
     
      Write('Appuyez sur la touche Entr'#130'e... ');
      ReadLn;
    end.
    Mais cela suppose que le compilateur puisse vérifier la condition, c'est-à-dire qu'il utilise un type de donnée capable de représenter la valeur somme + 2000. Est-ce que ça fonctionnerait avec TPW 1.5, par exemple ?
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  6. #6
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 552
    Points : 3 920
    Points
    3 920
    Par défaut
    Sans avoir testé l'idée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if somme + 2000 <= High(integer) then
    elle me paraît saugrenue (je pense qu'elle doit lêtre aussi pour Roland) car on retombe sur le problème initial, en fait au premier dépassement, la valeur de somme + 2000 sera négative et le test sera donc toujours positif. Une solution, bancale, consisterait à faire le même test en convertissant en réel, mais bon ça vaut ce que ça vaut ...

    Mais lagareg devrait préciser son idée...

    Ce problème de type provient sans doute d'un vieux compilo, type TurboPascal, c'est ça ?

    Je pense à deux solutions :
    - Passer à FreePascal, un peu plus moderne quand même, les entiers sont sur 4 octets, ta somme passe largement.
    - changer le type Integer -> LONGINT (selon le cours : http://cyberzoide.developpez.com/info/turbo/chap4.php3, ça fait longtemps que j'ai pas travaillé avec TP).

    Ce fil de discussion met bien en évidence le soin avec lequel il faut définir les types et structures de données et les faiblesses des programmes en général.

    @+

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  7. #7
    ALT
    ALT est déconnecté
    Membre émérite
    Avatar de ALT
    Homme Profil pro
    Retraité
    Inscrit en
    Octobre 2002
    Messages
    1 234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 234
    Points : 2 338
    Points
    2 338
    Par défaut
    Il existe une directive de compilation ( (*$Q+*) )qui permet de détecter ces dépassements.
    Avec un (*$i-*) & un (*$i+*) encadrant la somme, lié à un ioresult, on devrait pouvoir circonvenir le sinistre.
    Exemple, à titre d'illustration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (*$Q+*) (** peut aussi s'écrire {Q+} **)
    ...
    (*$I-*)
    somme:=65535+1; (** si on a un entier non signé sur 16 bits, on dépasse le maximum **)
    if (ioresult<>0 then message_erreur;
    (*$I+*)
    Et hop ! si dépassement, pas de plantage, mais un message d'erreur qui prévient l'utilisateur, ce qui est beaucoup plus sympa.
    « Un peuple qui est prêt à sacrifier un peu de liberté contre un peu de sécurité, ne mérite ni l'une, ni l'autre, et finira par perdre les deux. »
    Attribué indistinctement à :
    Thomas Jefferson
    Benjamin Franklin
    Albert Einstein !

Discussions similaires

  1. Rechercher le résultat d'une somme ?
    Par toss.net dans le forum Requêtes
    Réponses: 4
    Dernier message: 10/04/2010, 08h14
  2. Récupérer résultat d'une somme
    Par alex2746 dans le forum JDBC
    Réponses: 1
    Dernier message: 25/02/2010, 23h52
  3. Résultats incorrects d'une vue
    Par Njoannides dans le forum Requêtes
    Réponses: 1
    Dernier message: 01/07/2009, 22h12
  4. Afficher les résultats nuls d'une requête somme
    Par vorjan dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 08/08/2008, 01h54
  5. Réponses: 4
    Dernier message: 07/07/2008, 09h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo