Mon code plante après un second calcul ... [Résolu]

Signaler
Messages postés
31
Date d'inscription
lundi 14 mai 2012
Statut
Membre
Dernière intervention
21 août 2012
-
JacKrauser
Messages postés
31
Date d'inscription
lundi 14 mai 2012
Statut
Membre
Dernière intervention
21 août 2012
-
Bonjour à tous, voilà j'ai un problème concernant mon code sur le calcul d'équation du troisième degré.
Lors de sa première exécution tout va bien, mais lors de la seconde exécution, mon programme plante.
Voici le code :
unit Pordre3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TFordre3 = class(TForm)
    btnCalcul: TButton;
    btnRetour: TButton;
    GroupBox2: TGroupBox;
    lbExemple: TLabel;
    GroupBox3: TGroupBox;
    lbExemple2: TLabel;
    lbExemple3: TLabel;
    lbExemple5: TLabel;
    lbExemple4: TLabel;
    edInconnueA: TEdit;
    edInconnueB: TEdit;
    edInconnueC: TEdit;
    edInconnueD: TEdit;
    GroupBox4: TGroupBox;
    lbResultat: TLabel;
    lbResultat2: TLabel;
    GroupBox5: TGroupBox;
    Label1: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label2: TLabel;
    edPrecision: TEdit;
    procedure btnCalculClick(Sender: TObject);
    procedure btnRetourClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure edInconnueAKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure edInconnueBKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure edInconnueCKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure edInconnueDKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure edPrecisionKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure btnCalculKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure btnRetourKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure edPrecisionChange(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Fordre3: TFordre3;
  r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 : real;
  s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 : real;
  debut : extended = -1000000;
  fin : extended = 1000000;
  x, y, z, module, racine, pol, q, p, a, b, c, d, a2, b2, c2, a3, b3, c3, precision, delta, X1, X2 : real;
  codeA, codeB, codeC, codeD, codeP : integer;
implementation

{$R *.dfm}

procedure TFordre3.btnRetourClick(Sender: TObject);
begin
  Close;
end;

procedure TFordre3.FormActivate(Sender: TObject);
begin
  edInconnueA.SetFocus;
end;

procedure TFordre3.edInconnueAKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then btnCalculClick(Self);
  if Key = VK_ESCAPE then close;
end;

procedure TFordre3.edInconnueBKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then btnCalculClick(Self);
  if Key = VK_ESCAPE then close;
end;

procedure TFordre3.edInconnueCKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then btnCalculClick(Self);
  if Key = VK_ESCAPE then close;
end;

procedure TFordre3.edInconnueDKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then btnCalculClick(Self);
  if Key = VK_ESCAPE then close;
end;

procedure TFordre3.edPrecisionKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then btnCalculClick(Self);
  if Key = VK_ESCAPE then close;
end;

procedure TFordre3.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_ESCAPE then close;
end;

procedure TFordre3.btnCalculClick(Sender: TObject);
begin
  //vérification des valeurs renseignées
  val(edinconnueA.text,r0,codeA);
  val(edinconnueB.text,r1,codeB);
  val(edinconnueC.text,r3,codeC);
  val(edinconnueD.text,r5,codeD);
  val(edprecision.text,precision,codeP);
  if (codeA<>0) then
  begin
    showmessage('Veuillez rentrer un nombre dans la cellule a.');
    edinconnueA.text:='';
    edinconnueA.SetFocus;
    codeA:=1;
  end;
  if (codeB<>0) then
  begin
    showmessage('Veuillez rentrer un nombre dans la cellule b.');
    edinconnueB.text:='';
    edinconnueB.SetFocus;
    codeB:=1;
  end;
  if (codeC<>0) then
  begin
    showmessage('Veuillez rentrer un nombre dans la cellule a.');
    edinconnueC.text:='';
    edinconnueC.SetFocus;
    codeC:=1;
  end;
  if (codeD<>0) then
  begin
    showmessage('Veuillez rentrer un nombre dans la cellule a.');
    edinconnueD.text:='';
    edinconnueD.SetFocus;
    codeD:=1;
  end;
  if (codeP<>0) then
  begin
    showmessage('Veuillez rentrer un noombre pour la précision souhaitée.');
    edprecision.Text:='';
    edprecision.SetFocus;
    codeP:=1;
  end;

  precision:=exp(precision*ln(10));
  pol := r0 * (x*x*x) + r1 * (x*x) + r3 * x + r5;
          
if ((codeA+codeB+codeC+codeD+codeP=0) and (precision<>0)) then
  begin

    if (r0>0) then
    begin
      while ((pol <= -0.00001) or (pol >= 0.00001)) do
      begin
        x := debut + ((fin - debut)/2);
        pol := r0 * (x*x*x) + r1 * (x*x) + r3 * x + r5;
        if (pol < 0) then debut := x else fin := x;
      end;
    end
    else
      while ((pol <= -0.00001) or (pol >= 0.00001)) do
      begin
        x := debut + ((fin - debut)/2);
        pol := r0 * (x*x*x) + r1 * (x*x) + r3 * x + r5;
        if (pol < 0) then fin := x else debut := x;
      end;
    end;

    a3 := r0;
    a2 := r1 - (a3 * (-x));
    b3 := a2;
    b2 := r3 - (b3 * (-x));
    c3 := b2;
    r0 := a3;
    r1 := b3;
    r3 := c3;
    x := ROUND(x*precision)/precision;

  //fonction second degré

  //delta réel
  r7:=r1*r1+(r2*r2)*(-1)-4*r0*r3;
  //delta imaginaire
  r8:=2*r2*r1-4*r0*r4;
  if r0=0 then
  begin
    if ((r1=0) and (r2=0) and (r3=0) and (r4=0)) then
    begin
      lbResultat.Caption:='Les solutions sont infinies.';
      lbResultat2.Caption:='';
    end
    else
    if ((r1=0) and (r2=0)) then
    begin
      lbResultat.Caption:='Impossible de diviser par 0.';
      lbResultat2.Caption:='';
    end
    else
    if ((r3=0) and (r4=0)) then
    begin
      lbResultat.Caption:='Il y a deux solutions.';
      lbResultat2.caption:='X1 = '+FloatToStr(X)+' et X2 = 0';
    end
    else
  //fonction du premier degré
      if ((r2=0) or (r4=0)) then
      begin
        x:=r3*r1-(r4*(r2*(-1)));
        s4:=r4*r1+(r2*(-1))*r3;
        y:=r1*r1+r2*r2;
        s1:=ROUND((-x/y)*precision)/precision;
        s2:=ROUND((-s4/y)*precision)/precision;
        lbResultat.caption:='Il y a deux solutions.';
        lbResultat2.caption:='X1 = '+FloatToStr(X)+' et X2 = '+FloatToStr(s1)+' + '+FloatToStr(s2)+'i';
      end
      else
      begin
        s1:=ROUND((-r3/r1)*precision)/precision;
        lbResultat.Caption:='Il y a deux solutions.';
        lbResultat2.caption:='X1 = '+FloatToStr(X)+' et X2 = '+FloatToStr(s1);
      end
      end
      else
  //fonction du second degré
        if r8<>0 then
        begin
          module:=sqrt(r7*r7+r8*r8);
          x:=sqrt((r7+module)/2);
          y:=(r8/2)/x;
          s1:=ROUND(((-r1-x)/(2*r0))*precision)/precision;
          s2:=ROUND(((-r2-y)/(2*r0))*precision)/precision;
          s3:=ROUND(((-r1+x)/(2*r0))*precision)/precision;
          s4:=ROUND(((-r2+y)/(2*r0))*precision)/precision;
          lbResultat.Caption:='Il y a trois solutions.';
          lbResultat2.caption:='X1 = '+FloatToStr(X)+', X2 = '+FloatToStr(s1)+' + '+FloatToStr(s2)+'i et X3 = '+FloatToStr(s3)+' + '+FloatToStr(s4)+'i';
        end
        else
        begin
          racine:=sqrt(abs(r7));
          if r7>0 then
          begin
            s1:=ROUND(((-r1-racine)/(2*r0))*precision)/precision;
            s3:=ROUND(((-r1+racine)/(2*r0))*precision)/precision;
            lbResultat.Caption:='Il y a trois solutions.';
            lbResultat2.caption:='X1 = '+FloatToStr(X)+', X2 = '+FloatToStr(s1)+' et X3 = '+FloatToStr(s3);
          end
          else
            if r7<0 then
            begin
              s1:=ROUND((-r1/(2*r0))*precision)/precision;
              s2:=ROUND((racine/(2*r0))*precision)/precision;
              s3:=s1;
              s4:=s2;
              lbResultat.Caption:='Il y a trois solutions.';
              lbResultat2.caption:='X1 = '+FloatToStr(X)+', X2 = '+FloatToStr(s1)+' - '+FloatToStr(s2)+'i et X3 = '+FloatToStr(s1)+' + '+FloatToStr(s2)+'i';
            end
            else
            begin
              s1:=ROUND((-r1/(2*r0))*precision)/precision;
              lbResultat.Caption:='Il y a une solution.';
              lbResultat2.caption:='X1 = '+FloatToStr(X)+' et X2 = '+FloatToStr(s1);
            end;
  end;
  edInconnueA.SetFocus;
end;

procedure TFordre3.btnCalculKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then btnCalculClick(Self);
  if Key = VK_ESCAPE then close;
end;

procedure TFordre3.btnRetourKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_ESCAPE then close;
end;

procedure TFordre3.edPrecisionChange(Sender: TObject);
begin
  //vérification de la précision souhaitée
  val(edprecision.Text,precision,codeP);

  //si la précision demandée est inférieure à zéro ou supérieure à 9
  if (((precision<0) or (precision>9) or (codeP<>0)) and (edPrecision.Text<>'')) then
  begin
  showmessage('Veuillez rentrer un nombre compris entre 0 et 9 pour la précision.');
  edprecision.text:='';
  edprecision.SetFocus;
  end;

  //affichage de l'exemple de précision
  if (edPrecision.text<>'') then
  begin
  precision:=ROUND(strtofloat(edPrecision.text));
  precision:=exp(precision*ln(10));
  Label4.caption:=floattostr(1/precision);
  end;

  //exmemple vide si cellule de précision non renseignée
  if (edPrecision.text='') then
  Label4.Caption:='';
end;

end.


Avez vous une solution ? Je suis sous Delphi 7.

2 réponses

Messages postés
3809
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
25 janvier 2020
35
Salut,

évite les variables globales si elles ne sont pas nécessaires ....

ici tu déclares des variables globales initialisées et tu changes leurs valeurs dans une procédure en local ... à la deuxième exécution elles auront les dernières valeurs attribuées par le dernier appel à la procédure.


la solution déclarer des variables locale ou réinitialiser les variables en début de procédure:

Ainsi en ajoutant ceci au début de ton code ça devrait fonctionner:

procedure TFordre3.btnCalculClick(Sender: TObject);
begin
  debut := -1000000;
  fin := 1000000;
  //vérification des valeurs renseignées
  ...

[hr]@+Cirec
[hr]
Messages postés
31
Date d'inscription
lundi 14 mai 2012
Statut
Membre
Dernière intervention
21 août 2012

Ca marche :D
Je n'y avais pas pensé...
Merci Cirec, à croire que tu es le sauveur du forum