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

 Delphi Discussion :

Problème d'arrondi en Delphi


Sujet :

Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2009
    Messages : 27
    Points : 38
    Points
    38
    Par défaut Problème d'arrondi en Delphi
    Bonjour,
    J'ai un problème d'arrondi, j'ai le chiffre 0.865 et je veux comme résultat 0.87
    Mais toutes les fonctions que j'ai essayées en Delphi 2010 me donnent le résultat 0.86 ?

    Quelqu'un pourrait m'éclairer ???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    nbr := 0.865;
    
      RoundTo(nbr,-2);
      Format('%11.2f',[nbr]);
      FloatToStrF(nbr, ffFixed,11, 2);
      FormatFloat('0.00',nbr);
      SimpleRoundTo(nbr,-2);

    Merci dans l'attente de vous lire

  2. #2
    Membre à l'essai
    Inscrit en
    Mai 2006
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 26
    Points : 16
    Points
    16
    Par défaut
    Salut

    si je fais ça chez moi ça marche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.btn1Click(Sender: TObject);
    var nbr:Single;
    begin
      nbr:=0.865;
      showmessage (floattostr(RoundTo(nbr,-2)));
    end;
    avec Delphi 7 Lite

  3. #3
    Membre habitué
    Inscrit en
    Juillet 2007
    Messages
    113
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2007
    Messages : 113
    Points : 170
    Points
    170
    Par défaut
    Le mode d'arrondi de delphi par défaut est l'arrondi bancaire, lorsque la valeur est à mi-chemin l'arrondi va vers la valeur paire. dans ton exemple 0.865 va donc vers 0.86 plutot que vers 0.87 dont le dernier chiffre est impaire.
    http://docwiki.embarcadero.com/Libra...r/System.Round

    Si tu veux avoir un arrondi au dessus (ce qu'on apprends à l'école) il faut que tu modifies le roundMode
    http://docwiki.embarcadero.com/CodeE...dMode_(Delphi)

    Je pense que ces infos concernent toutes les versions de Delphi mais je peux me tromper

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 846
    Points
    24 846
    Par défaut
    Delphi XE2 Professional

    Single => RoundTo = 0.87 (à partir de nbr = 0,865000009536743, et oui, le Single est imprécis)
    Double => RoundTo = 0.86 (à partir de nbr = 0,865)
    Double => SimpleRoundTo = 0.86 (à partir de nbr = 0,865) // Ce qui est contraire à ce que dit la documentation de XE2 !
    Double => CeilTo = 0.87 (à partir de nbr = 0,865)

    Voici l'exemple
    SimpleRoundTo(1.234, -2) = 1.23
    SimpleRoundTo(1.235, -2) = 1.24
    On a déjà beaucoup discuté à ce sujet
    Utilisation de l'arrondi sur un calcul
    roundto simperoundto currency arrondi incorrect

    Il manque vraiment une fonction FloorTo et CeilTo qui serait explicitement l'arrondi par le bas ou par le haut !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function CeilTo(const AValue: Double; const ADigit: TRoundToRange): Double;
    var
      LFactor: Double;
    begin
      LFactor := IntPower(10, ADigit);
      Result := Ceil(AValue / LFactor) * LFactor;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 072
    Points
    1 072
    Par défaut
    Salut,

    Il manque vraiment une fonction FloorTo et CeilTo qui serait explicitement l'arrondi par le bas ou par le haut !
    il existe aussi la méthode "SetRoundMode"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      nbr:=0.865;
      SetRoundMode(rmDown);
      showmessage (floattostr(RoundTo(nbr,-2)));  // Donne 0.86
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      nbr:=0.865;
      SetRoundMode(rmUp);
      showmessage (floattostr(RoundTo(nbr,-2)));  // Donne 0.87
    Edit:
    il serait préférable de l'utiliser ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var nbr:Single;
        OldRndMode: TFPURoundingMode;
    begin
      nbr:=0.865;
      OldRndMode := SetRoundMode(rmDown);
      showmessage (floattostr(RoundTo(nbr,-2)));
      SetRoundMode(OldRndMode);
    end;
    afin de récupérer le mode initiale

    4 paramètres son dispo en tout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      TFPURoundingMode = (rmNearest, rmDown, rmUp, rmTruncate);

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2009
    Messages : 27
    Points : 38
    Points
    38
    Par défaut Mon problème est résolu
    Bonjour,

    Merci beaucoup mais au début même en précisant SetRoundMode(rmUp) et me donnait toujours 0.86. Mais maintenant tous fonctionne en utilisant la fonction ci-dessous avant :

    SetPrecisionMode(pmDouble);

    je sais pas pourquoi je suis obliger de préciser cette ligne avant mais bon ça fonctionne.

    Merci

  7. #7
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 072
    Points
    1 072
    Par défaut
    par défaut tu es en quelle précision "GetPrecisionMode"?

    chez moi j'ai pmExtended par défaut et tout fonctionne sans même besoin de préciser SetRoundMode(rmUp)

    Edit:
    après quelques testes supplémentaire il semblerait que la version de Delphi utilisé joue un rôle ...

    avec D7 peut importe le type (Single, Double, Extended) le résultat donne 0.87
    mais avec D2009 seul le type Single donne 0.87 et les autres 0.86 (peu importe l'utilisation ou non de PrecisionMode et RoundMode !!!

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2009
    Messages : 27
    Points : 38
    Points
    38
    Par défaut
    Bonjour Cirec,

    Pour répondre à ta question, par défaut j'ai aussi la valeur pmExtended

    Pour ton info, si je garde ma valeur par défaut qui est pmExtended ¸ça fonctionne pas: Voir l'exemple ci-dessous:
    nbr := 0.865;
    showMessage (Format('%11.2f',[nbr])); // = 0.86
    SetPrecisionMode(pmDouble);
    showMessage (Format('%11.2f',[nbr])); // = 0.87

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème d'impression avec delphi
    Par Bourak dans le forum Langage
    Réponses: 1
    Dernier message: 12/11/2005, 17h13
  2. problèmes aide en ligne Delphi 2005
    Par philippe.vernhes dans le forum Delphi .NET
    Réponses: 4
    Dernier message: 25/10/2005, 19h35
  3. Problème avec EInOutError sous delphi 2005
    Par Teb dans le forum Langage
    Réponses: 3
    Dernier message: 19/08/2005, 11h48
  4. Problème d'installation de Delphi 2005
    Par laclac dans le forum EDI
    Réponses: 1
    Dernier message: 29/07/2005, 12h53
  5. Problème d'arrondi
    Par ptitsoleil87 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 07/01/2005, 09h37

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