Delphi Fonction Frac()

Résolu/Fermé
yunamdr Messages postés 14 Date d'inscription jeudi 29 avril 2010 Statut Membre Dernière intervention 19 septembre 2010 - 12 sept. 2010 à 13:30
yunamdr Messages postés 14 Date d'inscription jeudi 29 avril 2010 Statut Membre Dernière intervention 19 septembre 2010 - 19 sept. 2010 à 17:18
Bonjour,
je vous contacte aujourd'hui car je dois réaliser un devoir pour mon école.
Je dois faire un programme qui permet de calculer la répartition optimale en billets et en pièces (argent suisse) en fonction de la somme saisie par l'utilisateur.
Donc je dois traiter les billets de :
1000
200
100
50
20
10
et les pièces de
5
2
1
0.5
0.2
0.1
0.05

J'ai réussi à traiter tous les cas de figures pour les billets et les pièces de 5, 2, 1, 0.5
grâce à deux fonctions.

Je vous donne le code source en entier

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    EdArgent: TEdit;
    PnDeco: TPanel;
    LbBillets: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    LbMille: TLabel;
    Label7: TLabel;
    LbCinq: TLabel;
    Label9: TLabel;
    LbDeuxCent: TLabel;
    Label11: TLabel;
    LbDeux: TLabel;
    Label13: TLabel;
    LbCent: TLabel;
    Label15: TLabel;
    LbUn: TLabel;
    Label17: TLabel;
    LbCinquante: TLabel;
    Label19: TLabel;
    LbCinquanteCentimes: TLabel;
    Label21: TLabel;
    LbVingt: TLabel;
    Label23: TLabel;
    LbVingtCentimes: TLabel;
    Label25: TLabel;
    LbDix: TLabel;
    Label27: TLabel;
    LbDixCentimes: TLabel;
    Label29: TLabel;
    LbCinqCentimes: TLabel;
    BtCalcul: TButton;
    BtReset: TButton;
    LbConcigne: TLabel;
    LbIndication: TLabel;
    LbMonnaie: TLabel;
    procedure BtResetClick(Sender: TObject);
    procedure EdArgentClick(Sender: TObject);
    procedure BtCalculClick(Sender: TObject);
    procedure Reinitialisation();
    procedure EdArgentKeyPress(Sender: TObject; var Key: Char);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;
  Nombre : integer;
  NombreCentime : Extended;

implementation

{$R *.dfm}
procedure TForm1.Reinitialisation();
begin
  LbMille.caption := '0';
  LbDeuxCent.caption := '0';
  LbCent.caption := '0';
  LbCinquante.caption := '0';
  LbVingt.caption := '0';
  LbDix.caption := '0';
  LbCinq.caption := '0';
  LbDeux.caption := '0';
  LbUn.caption := '0';
  LbCinquanteCentimes.caption := '0';
  LbVingtCentimes.caption := '0';
  LbDixCentimes.caption := '0';
  LbCinqCentimes.caption := '0';
end;

(**********************************************************|
|  Traitement des Pieces Extended tout sauf 20 centimes                            |
|**********************************************************)
function CalculCentimes1(Pieces : Extended) : string;
var
  i : integer;
begin
// initialisation variables
  i := 0;
// boucle
       if (NombreCentime > 0) and (NombreCentime >= Pieces) and (frac(NombreCentime) >=  Pieces)  and (Trunc(NombreCentime) <> NombreCentime) then
       begin
         inc(i);
         NombreCentime := NombreCentime - Pieces;
       end;
// fin de la boucle
// attribution de la valeur de i à Result
  Result := IntToStr(i);
end;
(***************************************************|
|  Traitement des Pieces Extended de 20 centimes                        |
|***************************************************)
function CalculCentimes2(Pieces : Extended) : string;
var
  i : integer;
begin
// initialisation variables
  i := 0;
// boucle
  if (NombreCentime > 0)  and (frac(NombreCentime) >=  Pieces) and (Trunc(NombreCentime) <> NombreCentime) then
  begin
    if (frac(NombreCentime) = 0.5) or (frac(NombreCentime) = 0.9) or (frac(NombreCentime) = 0.4) then
    begin
      repeat
        NombreCentime := NombreCentime - Pieces;
        inc(i);
      until i = 2;
    end
    else
    begin
      repeat
        NombreCentime := NombreCentime - Pieces;
        inc(i);
      until i = 1;
    end;
  end;
// fin de la boucle
// attribution de la valeur de i à Result
  Result := IntToStr(i);
end;

(*************************************|
|  Traitement des valeurs entieres                      |
|*************************************)
function Calcul(Billet : integer) : String;
var
  i : integer;
begin
// initialisation variables
  i := 0;
// boucle
  if Nombre div Billet > 0 then
  begin
    repeat
      inc(i);
      Nombre := Nombre - Billet;
    until (Nombre div Billet <= 0);
  end;
// fin de la boucle
// attribution de la valeur de i à Result
  Result := IntToStr(i);
end;


procedure TForm1.BtResetClick(Sender: TObject);
begin
  EdArgent.Text := 'Saisir une somme d''argent, SVP !';
  Reinitialisation();
end;

procedure TForm1.EdArgentClick(Sender: TObject);
begin
  EdArgent.Text := '';
end;

procedure TForm1.BtCalculClick(Sender: TObject);
var
  Billet : Integer;
  Pieces : Extended;
begin
  Reinitialisation();
// teste de sécurité
  if (EdArgent.Text = '') or (EdArgent.Text = 'Saisir une somme d''argent, SVP !') then
    ShowMessage('Saisir une somme d''argent, SVP !');

(************************************|
|  Traitement des Pieces Extended    |
|************************************)
// initialisation variable
  NombreCentime := StrToFloat(EdArgent.Text);
// teste d'optimisation
  if (Trunc(NombreCentime) <> NombreCentime) then
  begin
// traitement de 50 centimes
    Pieces := 0.5;
    LbCinquanteCentimes.caption:= CalculCentimes1(Pieces);
// traitement de 20 centimes
    Pieces := 0.2;
    LbVingtCentimes.caption:= CalculCentimes2(Pieces);


// traitement de 10 centimes
    Pieces := 0.1;


    LbDixCentimes.caption:= CalculCentimes1(Pieces);

// traitement de 5 centimes
    Pieces := 0.05;
    LbCinqCentimes.caption:= CalculCentimes1(Pieces);
  end;



(************************************|
|  Traitement des Billets Integer    |
|************************************)
// initialisation variables
  Nombre := trunc(NombreCentime);
// traitement 1000
  Billet := 1000;
  LbMille.Caption := calcul(Billet);
// traitement 200
  Billet := 200;
  LbDeuxCent.Caption := calcul(Billet);
// traitement 100
  Billet := 100;
  LbCent.Caption := calcul(Billet);
// traitement 50
  Billet := 50;
  LbCinquante.Caption := calcul(Billet);
// traitement 20
  Billet := 20;
  LbVingt.Caption := calcul(Billet);
// traitement 10
  Billet := 10;
  LbDix.Caption := calcul(Billet);
// traitement 5
  Billet := 5;
  LbCinq.Caption := calcul(Billet);
// traitement 2
  Billet := 2;
  LbDeux.Caption := calcul(Billet);
// traitement 1
  Billet := 1;
  LbUn.Caption := calcul(Billet);



end;

procedure TForm1.EdArgentKeyPress(Sender: TObject; var Key: Char);
begin
if not (key in['0'..'9',#8,'.']) then
    Key := #0;
end;

end.


Maintenant je vous expose mon problème,
j'utilise la fonction frac pour obtenir la valeur décimal de la variable NombreCentime
et je veux tester si cette valeur décimal est égal à la variable Pièces pour empêcher
l'affichage de la somme d'argent uniquement en pièces de 20 centimes.
Je vous donne un exemple :
NombreCentime = 1.4
Pièces = 0.4
quand je teste (frac(NombreCentime) >= Pièces) il m'affiche bien que frac NombreCentime = 0.4 et Pièces à 0.4 pourtant il m'écrit que ce teste est faux.
Je ne comprends pas pourquoi si quelqu'un peut m'aider en m'expliquant mieux l'effet de la fonction frac ou alors une erreur dans mon code, ça m'aiderait beaucoup.

Je vous remercie d'avance
Yunamdr

1 réponse

yunamdr Messages postés 14 Date d'inscription jeudi 29 avril 2010 Statut Membre Dernière intervention 19 septembre 2010
19 sept. 2010 à 17:18
J'ai trouvé la solution :)

au lieu de ce compliquer la vie avec des frac et autres il vaut mieux tout simplement tout traiter en centimes.

function unique à appeler :

// fonction de traitement du nombre de chaque monnaie
function Calcul(monnaie:integer):string;
var
i : integer;
begin
i := 0;
if ((Nombre div Monnaie) <> 0) then
begin
repeat
inc(i);
Nombre := Nombre - Monnaie;
until ((Nombre div Monnaie)= 0);
end;
Result:= IntToStr(i);
end;

action dans le bouton

Nombre := trunc(StrToFloat(EdArgent.text)*100);
// 100000 = nombre de centimes dans 1000 chf
LbMille.caption := Calcul(100000);
... pour toutes les monnaies.
0