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

Langage Delphi Discussion :

[D7] Problème d'arrondi


Sujet :

Langage Delphi

  1. #1
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut [D7] Problème d'arrondi
    Bonjour à tous,

    je cherche à extraire les 3 premières décimales d'un réel, mais l'arrondi ne se fait pas comme je voudrais :

    pour 1234,5655 je dois obtenir 566 car l'arrondi de 565,5 est 566.

    Frac(1234,5655) me donne 0, 565499999 ...

    et donc Round(Frac(1234,5655) * 1000 me donne 565 !

    Comment faire ? si j'ajoute un petit nombre, par exemple 10-4 est ce que cela fonctionnera à coup sûr ?

    A+
    Charly

  2. #2
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Nota : j'ai essayé avec SimpleRoundTo comme dans la FAQ, mais sans succès. je vais réessayer ...

    A+
    Charly

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 202
    Points : 41 443
    Points
    41 443
    Billets dans le blog
    63
    Par défaut
    Bonjour,

    Je n'ai pas de D7 dispo à l'instant T. Existait-il déjà la fonction d'arrondi bancaire Math.RoundTo et Math.SimpleRoundTo ? De plus, toujours dans l'unité Math il y a la possibilité de changer le mode Math.SetRoundMode

  4. #4
    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 073
    Points
    1 073
    Par défaut
    Bonjour,

    j'avais fait il y a quelques temps un petit prog avec D7 pour
    mieux visualiser les possibilités
    Nom : Arrondis&Précisions.png
Affichages : 112
Taille : 26,5 Ko
    Le Zip:
    Arrondis et Précisions.zip

    Cordialement,
    @+

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    alors il est toujours possible de truander avec un Trunc((x * 100) + 0.5)/100.

    EDIT: en fait, Trunc((x * 1000) + 0.5)/1000 dans ton cas

  6. #6
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Merci à tous les 3, mais je crois que cela ne marche pas à cause de Frac :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      Valeur := 1345.5655 ;
      NbDecimales := 3 ;
      SetPrecisionMode(pmExtended) ;
      SetRoundMode(rmNearest) ;
      Decimales := RoundTo(Frac(Valeur) * Power(10, NbDecimales), 0) ;   // Partie décimale du nombre à convertir
      BB := Frac(Valeur) ;
      AA := BB * Power(10, NbDecimales) ;
      CC := Power(10, NbDecimales) ;
      ShowMessage('Décimales : '+ FloatToStr(Decimales)+Chr(13)+
                  'Valeur : '+ FloatToStr(Valeur)+Chr(13)+
                  'NbDécimales : '+ IntToStr(NbDecimales)+Chr(13)+
                  'Frac(Valeur) : '+ FloatToStr(BB)+Chr(13)+
                  'Power(10, NbDecimales) : '+ FloatToStr(CC) +Chr(13)+
                  'Frac(Valeur) * Power(10, NbDecimales) : '+ FloatToStr(AA) ) ;
    Je vais essayer autrement (le but est d'extraire les NbDecimales premières décimales avec arrondi rmNearest que je ne connaissais pas !)

    A+
    Charly

  7. #7
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    J'ai fait un peu compliqué, mais qui fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      Valeur := 1345.5655 ;
      NbDecimales := 3 ;
      SetPrecisionMode(pmExtended) ;
      SetRoundMode(rmNearest) ;
      AA := Valeur * Power(10, NbDecimales) ;
      AA := RoundTo(AA, 0) ;
      AA := AA / Power(10, NbDecimales) ;
      Decimales := RoundTo((AA - Trunc(AA)) * Power(10, NbDecimales), 0) ;   // Partie décimale du nombre à convertir
      ShowMessage('Valeur : '+ FloatToStr(Valeur)+Chr(13)+
                  'NbDécimales : '+ IntToStr(NbDecimales)+Chr(13)+
                  'AA : '+ FloatToStr(AA)+Chr(13)+
                  'Résultat : '+ FloatToStr(Decimales)) ;
    Je vais essayer la solution de Paul qui ale mérite de la simplicité !

    A+
    Charly

  8. #8
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Trunc ne fonctionne pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      BB :=  1345.5655 ;
      NbDecimales := 3 ;
      CC := Trunc((BB * Power(10, NbDecimales)) + 0.5)/Power(10, NbDecimales) ;
      ShowMessage('Valeur : '+ FloatToStr(BB)+Chr(13)+
                  'NbDécimales : '+ IntToStr(NbDecimales)+Chr(13)+
                  'Résultat : '+ FloatToStr(CC)) ;
    Donne : 1234,565

    (BB et CC sont déclarés en Real)

    A+
    Charly

  9. #9
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Tous semble fonctionner avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      SetPrecisionMode(pmDouble) ;
      SetRoundMode(rmNearest) ;
    Merci à Cirec (et aux autres !)

    A+
    Charly

  10. #10
    Membre confirmé Avatar de blonde
    Femme Profil pro
    Développeur Delphi
    Inscrit en
    Septembre 2003
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Delphi

    Informations forums :
    Inscription : Septembre 2003
    Messages : 278
    Points : 480
    Points
    480
    Par défaut
    Avant qu'on ne referme la discussion, est-ce quelqu'un pourrait éclaire ma lanterne sur le fonctionnement du Trunc ?
    J'ai écrit un code équivalent à celui de Charly90, et j'ai le même comportement : les décimales trouvées sont 565, à la place de 566 juste après le Trunc.

    Dans la documentation D10 j'ai lu ça :

    Trunc renvoie une valeur Int64 qui correspond à la valeur arrondie de X (vers zéro).


    Ca veut dire quoi ?
    Pour ma part, j'ai toujours cru que tronquer, c'était simplement se débarrasser de la partie décimale.

  11. #11
    Membre confirmé Avatar de blonde
    Femme Profil pro
    Développeur Delphi
    Inscrit en
    Septembre 2003
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Delphi

    Informations forums :
    Inscription : Septembre 2003
    Messages : 278
    Points : 480
    Points
    480
    Par défaut
    Sinon, ceci fonctionne très bien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      e := 1234.5655;
      e := e - Trunc(e);
     
      milliemesI := Round(e * 1000);
      ShowMessage(IntToStr(milliemesI));

  12. #12
    Membre confirmé Avatar de blonde
    Femme Profil pro
    Développeur Delphi
    Inscrit en
    Septembre 2003
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Delphi

    Informations forums :
    Inscription : Septembre 2003
    Messages : 278
    Points : 480
    Points
    480
    Par défaut
    Et le code qui me pose question :

    J'ai tout bien détaillé, ce sont les 2 derniers ShowMessage qui me posent problème. Dans le principe, on ne devrait pas afficher exactement la même chose ?

    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
     
    var
     e : extended;
     e1000 : Extended;
     eFinal : Extended;
     multiplicateur : Integer;
     milliemesE : Extended;
     milliemesI : Integer;
     
    begin
     
     e := 1234.5655;
     multiplicateur := 1000;
     
     e1000 := Round(e * multiplicateur) ;
     
     ShowMessage(FloatToStr(e1000));
     
     eFinal := e1000 / multiplicateur;
     ShowMessage(FloatToStr(eFinal));
     
     ShowMessage(FloatToStr(eFinal - Trunc(e)));
     
     milliemesE := (eFinal - Trunc(e)) * multiplicateur;
     milliemesI := Trunc(milliemesE);
     
     ShowMessage(FloatToStr(milliemesE));
     ShowMessage(IntToStr(milliemesI));

  13. #13
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Bonjour Blonde,

    je n'ai pas encore regardé, mais je pense que Trunc doit aussi être sensible à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      SetPrecisionMode(pmDouble) ;
      SetRoundMode(rmNearest) ;
    A+
    Charly

  14. #14
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Non ce n'est pas cela ! mais ça doit être un problème de représentation des extended :

    566 est en fait 565,9999999... donc Trunc = 565

    A+
    Charly

  15. #15
    Membre confirmé Avatar de blonde
    Femme Profil pro
    Développeur Delphi
    Inscrit en
    Septembre 2003
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Delphi

    Informations forums :
    Inscription : Septembre 2003
    Messages : 278
    Points : 480
    Points
    480
    Par défaut
    J'ai essayé ça, tu vas voir, c'est drôle :

    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
    30
    31
    32
    33
    34
    35
    var
     e : extended;
     e1000 : Extended;
     eFinal : Extended;
     multiplicateur : Integer;
     milliemesE : Extended;
     milliemesI : Integer;
     
     oldPM : TFPUPrecisionMode;
    begin
     
      oldPM := GetPrecisionMode;
      SetPrecisionMode(pmDouble);
     
     e := 1234.5655;
     multiplicateur := 1000;
     
     e1000 := Round(e * multiplicateur) ;
     
     ShowMessage(FloatToStr(e1000));
     
     eFinal := e1000 / multiplicateur;
     ShowMessage(FloatToStr(eFinal));
     
     ShowMessage(FloatToStr(eFinal - Trunc(e)));
     
     milliemesE := (eFinal - Trunc(e)) * multiplicateur;
     milliemesI := Trunc(milliemesE);
     
     ShowMessage(FloatToStr(milliemesE));
     ShowMessage(IntToStr(milliemesI));
     
     SetPrecisionMode(oldPM);
     
    end;

  16. #16
    Membre confirmé Avatar de blonde
    Femme Profil pro
    Développeur Delphi
    Inscrit en
    Septembre 2003
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Delphi

    Informations forums :
    Inscription : Septembre 2003
    Messages : 278
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    Non ce n'est pas cela ! mais ça doit être un problème de représentation des extended :

    566 est en fait 565,9999999... donc Trunc = 565

    A+
    Charly
    Et si tu fais 566 * 1000 tu obtiens quoi ?
    566000 ou bien 565999 ?

  17. #17
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    avec FloatToStr, ça donne 566000, mais que fait FloatToStr ?

    Sinon avec pmDouble, tout fonctionne !

    A+
    Charly

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

Discussions similaires

  1. Problème d'arrondi
    Par rigobert dans le forum C
    Réponses: 28
    Dernier message: 05/04/2006, 12h56
  2. problème d'arrondi à 2 chiffres après virgule
    Par nerick dans le forum Langage
    Réponses: 1
    Dernier message: 05/01/2006, 17h26
  3. Problème d'arrondis
    Par steps5ive dans le forum Access
    Réponses: 5
    Dernier message: 09/12/2005, 17h35
  4. [DECIMAL] problème d'arrondi
    Par Boosters dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 28/11/2005, 15h30
  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