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 :

Utilisation de SetRoundMode et de RoundTo


Sujet :

Langage Delphi

  1. #1
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Par défaut Utilisation de SetRoundMode et de RoundTo
    Bonjour,

    Tout d'abord, je tiens à préciser que je travaille sous D2009.
    Je suis entrain de faire un petit composant et j'aimerai arrondir "mon float" soit par excès, soit par défaut, soit ne rien faire du tout, juste faire un tronquage.

    J'ai vu que l'on pouvait utiliser la fonction SetRoundMode avec les valeurs ci dessous :
    Citation Envoyé par Aide
    Valeur Signification
    rmNearest Arrondit à la valeur la plus proche.
    rmDown Arrondit vers moins l'infini.
    rmUp Arrondit vers plus l'infini.
    rmTruncate Tronque la valeur, en arrondissant les valeurs positives vers le bas et les valeurs négatives vers le haut.
    Soit je ne comprends pas ce que signifie ce qu'est arrondir vers l'infini, soit ça ne fonctionne pas...
    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SetRoundMode(rmDown);
      ShowMessage(FloatToStr(RoundTo(12.255,-2))); // Devrait donner 12.25
      SetRoundMode(rmUp);
      ShowMessage(FloatToStr(RoundTo(12.255,-2))); // Devrait donner 12.26
      SetRoundMode(rmNearest);
      ShowMessage(FloatToStr(RoundTo(12.255,-2))); // Devrait donner 12.26
      SetRoundMode(rmTruncate);
      ShowMessage(FloatToStr(RoundTo(12.255,-2))); // Devrait donner 12.25
    Je ne sais pas ce que vous en pensez

    Merci
    Ero-Sennin

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 969
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 969
    Par défaut
    Cela ne va pas te dépanner mais un copier/coller de ton code me donne bien les résultats que tu attends . (D2007)

    Peut-être une directive de compilation ?..

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 574
    Par défaut
    Salut

    Afin d'éclairer ta lanterne voici un exemple plus précis.

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        lw: TListView;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    uses
      Math;
     
    {$R *.dfm}
     
    function ArrondiParDefaut( Value: Double; Prec: Integer): Double;
    var
      rmSave: TFPURoundingMode;
    begin
      rmSave := GetRoundMode;
      try
        SetRoundMode(rmDown);
        Result := RoundTo(Value, Prec);
      finally
        SetRoundMode(rmSave);
      end;
    End;
     
    function ArrondiParExces( Value: Double; Prec: Integer): Double;
    var
      rmSave: TFPURoundingMode;
    begin
      rmSave := GetRoundMode;
      try
        SetRoundMode(rmUp);
        Result := RoundTo(Value, Prec);
      finally
        SetRoundMode(rmSave);
      end;
    End;
     
    function ArrondiParTronquage( Value: Double; Prec: Integer): Double;
    var
      rmSave: TFPURoundingMode;
    begin
      rmSave := GetRoundMode;
      try
        SetRoundMode(rmTruncate);
        Result := RoundTo(Value, Prec);
      finally
        SetRoundMode(rmSave);
      end;
    End;
     
    function ArrondiPlusProche( Value: Double; Prec: Integer): Double;
    var
      rmSave: TFPURoundingMode;
    begin
      rmSave := GetRoundMode;
      try
        SetRoundMode(rmTruncate);
        Result := RoundTo(Value, Prec);
      finally
        SetRoundMode(rmSave);
      end;
    End;
     
    procedure TForm1.Button1Click(Sender: TObject);
    const
      tab: array[0..3] of Double = (-25.255,-25.250,25.250,25.255);
    var
      I: integer;
    begin
      for I := Low(tab) to High(tab) do
      begin
        with lw.Items.Add do
        begin
          Caption := Format('%g', [tab[I]]);
          SubItems.Add(Format('%g', [ArrondiParExces(tab[I],-2)]));
          SubItems.Add(Format('%g', [ArrondiParDefaut(tab[I],-2)]));
          SubItems.Add(Format('%g', [ArrondiPlusProche(tab[I],-2)]));
          SubItems.Add(Format('%g', [ArrondiParTronquage(tab[I],-2)]));
        end;
      end;
    End;
     
    end.
    et pour le dfm
    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    object Form1: TForm1
      Left = 493
      Top = 188
      Width = 458
      Height = 297
      Caption = 'Form1'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object Button1: TButton
        Left = 32
        Top = 20
        Width = 75
        Height = 25
        Caption = 'Button1'
        TabOrder = 0
        OnClick = Button1Click
      end
      object lw: TListView
        Left = 28
        Top = 52
        Width = 409
        Height = 150
        Columns = <
          item
            Caption = 'Value'
          end
          item
            Caption = 'rmUp'
          end
          item
            Caption = 'rmDown'
          end
          item
            Caption = 'rmNearest'
          end
          item
            Caption = 'rmTruncate'
          end>
        TabOrder = 1
        ViewStyle = vsReport
      end
    end
    Le sens de l'infini te donne seulement le sens vers lequel l'arrondi est réalisé connaissant la précision (-2 signifie 2 décimales), -∞ signifie que l'on arrondit à la valeur immédiatement inférieure (arrondi par défaut), +∞ vers la valeur immédiatement supérieure (arrondi par excès).

    Il faut bien comprendre que les modes d'arrondi rmUp et rmDown sont des implémentations directes de la fonction mathématique partie entière E(X) (révise des cours de maths de terminale si nécessaire).

    Rem : Le mode d 'arrondi est restauré en fin de chaque routine car je fais la supposition que ce mode est global et permanent.

    Cdlt

    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."

  4. #4
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Cela ne va pas te dépanner mais un copier/coller de ton code me donne bien les résultats que tu attends . (D2007)

    Peut-être une directive de compilation ?..
    Très étrange! Moi j'ai que 12.26 qui sort

  5. #5
    Membre émérite
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Par défaut
    Bizarre, effectivement. Un bug de Delphi 2009 ?

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 945
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 945
    Billets dans le blog
    6
    Par défaut
    obtiens-tu également 4 fois 12,26 en passant la valeur à arrondir par variable ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  7. #7
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Par défaut
    Citation Envoyé par CapJack Voir le message
    Bizarre, effectivement. Un bug de Delphi 2009 ?
    Après revérification ce matin, toujours la même chose. J'ai fait un nouveau projet en mettant dans les uses, l'unité Math puis, un Button sur ma Form qui effectue ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SetRoundMode(rmDown);
    ShowMessage(FloatToStr(RoundTo(12.255,-2))); // Devrait donner 12.25
    SetRoundMode(rmUp);
    ShowMessage(FloatToStr(RoundTo(12.255,-2))); // Devrait donner 12.26
    SetRoundMode(rmNearest);
    ShowMessage(FloatToStr(RoundTo(12.255,-2))); // Devrait donner 12.26
    SetRoundMode(rmTruncate);
    ShowMessage(FloatToStr(RoundTo(12.255,-2))); // Devrait donner 12.25
    Citation Envoyé par tourlourou Voir le message
    obtiens-tu également 4 fois 12,26 en passant la valeur à arrondir par variable ?
    Que veux-tu dire par "Passer la valeur à arrondir par variable" ?

  8. #8
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 708
    Billets dans le blog
    65
    Par défaut
    Salut ,

    Citation Envoyé par ero-sennin Voir le message
    Que veux-tu dire par "Passer la valeur à arrondir par variable" ?
    je pense qu'il veut dire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    var i : .......; 
     
    i:=12.255;
    SetRoundMode(rmDown);
    ShowMessage(FloatToStr(RoundTo(i,-2))); // Devrait donner 12.25
    SetRoundMode(rmUp);
    ShowMessage(FloatToStr(RoundTo(i,-2))); // Devrait donner 12.26
    SetRoundMode(rmNearest);
    ShowMessage(FloatToStr(RoundTo(i,-2))); // Devrait donner 12.26
    SetRoundMode(rmTruncate);
    ShowMessage(FloatToStr(RoundTo(i,-2))); // Devrait donner 12.25

  9. #9
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 945
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 945
    Billets dans le blog
    6
    Par défaut
    c'est bien ça !

    2° question : peux-tu en mode débugage faire le suivi en pas-à-pas et vérifier le mode d'arrondi dans RoundTo ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  10. #10
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Par défaut
    Salut,

    Je viens d'effectuer le test en passant la valeur par variable, et rien n'y fait.
    Pas contre, je ne peux pas voir le mode d'arrondi dans RoundTo

  11. #11
    Membre émérite
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Par défaut
    Une petite recherche sur le net m'a convaincu qu'il y avait bien un problème.

    http://dn.codegear.com/search?q=Roun...s=y&allwords=y

    Et encore, toi tu as de la chance, il y en a qui trouveraient 12,54.
    Apparemment ça dépend du type de processeur, si j'ai bien tout compris.

    Tu as fais les mises à jour de Delphi ?

  12. #12
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Par défaut
    Bonsoir CapJack,

    Citation Envoyé par CapJack Voir le message
    Une petite recherche sur le net m'a convaincu qu'il y avait bien un problème.

    http://dn.codegear.com/search?q=Roun...s=y&allwords=y

    Et encore, toi tu as de la chance, il y en a qui trouveraient 12,54.
    Apparemment ça dépend du type de processeur, si j'ai bien tout compris.

    Tu as fais les mises à jour de Delphi ?
    Effectivement, je n'avais pas pensé à regarder de ce coté.
    D'après ce que j'ai pu lire, ça ne date pas d'hier ce bug! Il était déjà présent sous D7 ...
    Je pense que je vais me faire ma propre fonction de "troncage".
    Pour info, j'ai un P4 HT ... et j'avais déjà fais une mise à jour. J'ai regardé si il y en avait une nouvelle, mais non! Tant pis

    Merci bien pour votre aide

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

Discussions similaires

  1. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 16h57
  2. Réponses: 4
    Dernier message: 05/06/2002, 15h35
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 13h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 17h01
  5. Réponses: 2
    Dernier message: 21/03/2002, 00h01

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