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

Pascal Discussion :

Opérations sur les fractions


Sujet :

Pascal

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Inscrit en
    Mai 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations forums :
    Inscription : Mai 2012
    Messages : 8
    Points : 6
    Points
    6
    Par défaut Opérations sur les fractions
    Salut.
    Aidez-moi svp, j'ai un exercice dont je n'ai pas compris la question !!
    exercice:
    Soit le type fraction défini par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    type fraction=record
                        num:integer
                        den:integer
                        end;
    Écrire des sous programme chargés des opérations de:
    - addition, soustraction, multiplication et division de deux fractions.
    Alors c'est un exercice donné aux mathématiciens ; le problème est que je ne comprends pas le sens de la question, c.à.d pour l’addition, par exemple, est-ce que on met le résultat d’addition des deux fractions dans une variable de type fraction ou dans une variable réelle ? La même chose pour multiplication, etc. Merci d'avance.

  2. #2
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 085
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 085
    Points : 15 507
    Points
    15 507
    Billets dans le blog
    9
    Par défaut
    Bonjour !

    Il me semble que le résultat doit être une fraction. De toute façon, une fois qu'on a une fraction, on peut toujours obtenir le nombre décimal correspondant.

    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
    program fraction_01;
     
    type fraction = record
                      num: integer;
                      den: integer;
                    end;
     
    var
      f: fraction;
      r: real;
     
    begin
      f.num := 3;
      f.den := 2;
      r := f.num / f.den;
     
      WriteLn('f = ', f.num, ' / ', f.den);
      WriteLn('r = ', r);
     
      ReadLn;
    end.

  3. #3
    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
    à mon avis il faut rester dans des fractions entières 1/2 + 1/4 = 3/4

  4. #4
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 085
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 085
    Points : 15 507
    Points
    15 507
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    à mon avis il faut rester dans des fractions entières 1/2 + 1/4 = 3/4
    On pourrait même imaginer un affichage sur mesure, quelque chose comme ça :

    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
    program writefrac1;
     
    uses
      SysUtils;
     
    type
      tOp = (p, m, f, d);
     
    { plus, moins, fois, divisé par }
     
    const
      signe: array[p..d] of char = ('+', '-', '*', '/');
     
    procedure WriteFracOp(a, b, c, d, e, f: integer; op: tOp);
     
    { a/b + c/d = e/f }
    { a/b - c/d = e/f }
    { a/b * c/d = e/f }
    { a/b / c/d = e/f }
     
    begin
      WriteLn(' ', IntToStr( a ):3, '     ', IntToStr( c ):3, '     ', IntToStr( e ):3);
      WriteLn('----- ' + signe[op] + ' ----- ' + '=' + ' -----');
      WriteLn(' ', IntToStr( b ):3, '     ', IntToStr( d ):3, '     ', IntToStr( f ):3);
    end;
     
    begin
      WriteFracOp(1,3, 1,4, 7,12, p);
      ReadLn;
    end.

  5. #5
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    Allé, parce que plus on est de fou plus on ris et que le sujet m'a interpelé, parce que ça fait longtemps que j'avais pas toucher aux fractions et que je voulais m'entrainer encore sur la surcharge d'opé :

    j'ai juste laissé la routine pour les divisions de fraction vide (à faire) en mode comment embrouiller quelqu'un avec un code trop complexe pour lui qui ne risque pas de compiler sur autre chose que Delphi

    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
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
     
    unit UFraction;
     
    interface
     
    {$IF RTLVersion >= 18.0}
      {$DEFINE RECOP}
    {$IFEND}
    type
      Float = {$IFDEF RECOP}extended{$ELSE}double{$ENDIF};
     
      TFraction = record
        Numerateur, Denominateur : integer;
      {$IFDEF RECOP}
        public
          class function Create(aNumerateur, aDenominateur: integer): TFraction; static;
          class function Simplify(A:TFraction): TFraction; static;
     
          { N/D = réel }  class operator Explicit(A: TFraction): Float;   // Float := Fraction
          { N/D = réel }  class operator Implicit(A: TFraction): Float;   // Float = Float(Fraction)
     
          { a = a/1 }     class operator Explicit(A: Integer): TFraction; // Fraction := integer [+-*/div] Fraction
          { a = a/1 }     class operator Implicit(A: Integer): TFraction; // Fraction = TFraction(integer)
     
          { a/b + c/d }   class operator Add(A,B: TFraction): TFraction;
          { a/b - c/d }   class operator Subtract(A,B: TFraction): TFraction;
          { a/b * c/d }   class operator Multiply(A,B: TFraction): TFraction;
          { a/b / c/d }   class operator Divide(A,B: TFraction): TFraction;
          { a/b div c/d } class operator IntDivide(A,B: TFraction): TFraction;
     
          { simplfy by round } class operator Round(A: TFraction): TFraction;
      {$ENDIF}
      end;
     
    {$IFNDEF RECOP}
    function FractionCreate(aNumerateur, aDenominateur: integer): TFraction;
    function FractionSimplify(A: TFraction): TFraction;
    function FractionToFloat(A: TFraction): Float;
    function IntToFraction(A: integer): TFraction;
    function FractionAdd(A,B: TFraction): TFraction;
    function FractionSubtract(A,B: TFraction): TFraction;
    function FractionMultiply(A,B: TFraction): TFraction;
    function FractionDivide(A,B: TFraction): TFraction;
    {$ENDIF}
     
    implementation
     
    { TFraction }
     
    {$IFDEF RECOP}class operator TFraction.{$ELSE}function Fraction{$ENDIF}Add(A, B: TFraction): TFraction;
    begin
      // 1/2 + 3/4  = ((1*4)+(3*2))/4*2 = (4+6)/8 = 10/8 = 1.25
      // 0.5 + 0.75 = 1.25
      result.Numerateur   := (A.Numerateur*B.Denominateur)+(B.Numerateur*A.Denominateur);
      result.Denominateur := (A.Denominateur*B.Denominateur)
    end;
     
    {$IFDEF RECOP}class function TFraction.{$ELSE}function Fraction{$ENDIF}Create(aNumerateur, aDenominateur: integer): TFraction;
    begin
      result.Numerateur   := aNumerateur;
      result.Denominateur := aDenominateur;
    end;
     
    {$IFDEF RECOP}class function TFraction.{$ELSE}function Fraction{$ENDIF}Simplify(A:TFraction): TFraction;
    var M, DC: integer;
     
    begin
      M := A.Denominateur;
      if A.Numerateur < A.Denominateur then
        M := A.Numerateur;
     
      result := A;
     
      DC := M;
     
      while DC > 0 do
      begin
        if ((result.Numerateur mod DC) = 0) and ((result.Denominateur mod DC) = 0) then
        begin
          result.Numerateur   := result.Numerateur   div DC;
          result.Denominateur := result.Denominateur div DC;
          break;
        end;
        dec(DC);
      end;
    end;
     
    {$IFDEF RECOP}class operator TFraction.{$ELSE}function Fraction{$ENDIF}Divide(A, B: TFraction): TFraction;
    begin
      // TODO  héhéhé
    end;
     
    {$IFDEF RECOP}class operator TFraction.explicit{$ELSE}function FractionToFloat{$ENDIF}(A: TFraction): Float;
    begin
      result := A.Numerateur / A.Denominateur;
    end;
    {$IFDEF RECOP}class operator TFraction.implicit(A: TFraction): Float;
    begin
      result := A.Numerateur / A.Denominateur;
    end;
    {$ENDIF}
     
    {$IFDEF RECOP}class operator TFraction.explicit{$ELSE}function IntToFraction{$ENDIF}(A: integer): TFraction;
    begin
      result.Numerateur   := A;
      result.Denominateur := 1;
    end;
    {$IFDEF RECOP}class operator TFraction.implicit(A: integer): TFraction;
    begin
      result.Numerateur   := A;
      result.Denominateur := 1;
    end;
    {$ENDIF}
     
    {$IFDEF RECOP}
    class operator TFraction.IntDivide(A, B: TFraction): TFraction;
    begin
      result := A / B; // call TFraction.Divide
    end;
    {$ENDIF}
     
    {$IFDEF RECOP}class operator TFraction.{$ELSE}function Fraction{$ENDIF}Multiply(A, B: TFraction): TFraction;
    begin
      // 1/2 * 2/4 = (1*2) / (2*4) = 2/8 {1/4} = 0.5 * 0.5 = 0.25 {1/4}
      result.Numerateur   := A.Numerateur   * B.Numerateur;
      result.Denominateur := A.Denominateur * B.Denominateur;
    end;
     
    {$IFDEF RECOP}class operator TFraction.{$ELSE}function Fraction{$ENDIF}Subtract(A, B: TFraction): TFraction;
    begin
      // 1/2 - 3/4  = ((1*4)-(3*2))/4*2 = (4-6)/8 = -2/8 = -0.25
      // 0.5 - 0.75 = -0.25
      result.Numerateur   := abs((A.Numerateur*B.Denominateur)-(B.Numerateur*A.Denominateur));
      result.Denominateur := (A.Denominateur*B.Denominateur)
    end;
     
    {$IFDEF RECOP}class operator TFraction.Round(A: TFraction): TFraction;
    begin
      result := TFraction.Simplify(A);
    end;
    {$ENDIF}
     
    end.
    contient :
    Création d'un TFraction,
    Calcul réel de la fraction,
    Addition, Soustraction, Multiplication de fraction,
    simplification de fraction (4/16=1/4, 20/1000=1/50),
    conversion d'un entier en fraction (I/1).

    calculs réalisable (avec ou sans simplification) :

    R = A/B + C/D
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    R := AB.Create(A,B) + CD.Create(C,D)
    R = A/B - C/D
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    R := AB.Create(A,B) - CD.Create(C,D)
    R = A/B * C/D
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    R := AB.Create(A,B) * CD.Create(C,D)
    R = a + B/C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    R := TFraction(a) + BC.Create(B,C)
    R = a - B/C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    R := TFraction(a) - BC.Create(B,C)
    R = a * B/C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    R := TFraction(a) * BC.Create(B,C)
    R = a * B/C - d * E/F + G/H * i
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    R := round(TFraction(a) * BC.Create(B,C) - TFraction(d) * EF.Create(E,F) + GH.Create(G,H) * TFraction(i))
    Exemple type sur Delphi2009 :

    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
     
    procedure TForm13.Button1Click(Sender: TObject);
    var A, B, R, S: TFraction;
    begin
      A := TFraction.Create(3,9);
      B := TFraction.Create(4,11);
     
      R := A + B;
      S := round(R);
      ListBox1.Items.Add(
        format(
          '%d/%d + %d/%d = %d/%d = %d/%d = {%.3f ° %.3f = %.3f)',
          [ A.Numerateur, A.Denominateur,
            B.Numerateur, B.Denominateur,
            R.Numerateur, R.Denominateur,
            S.Numerateur, S.Denominateur,
            Float(A), Float(B), Float(R)]
        )
      );
     
      R := A - B;
      S := round(R);
      ListBox1.Items.Add(
        format(
          '%d/%d - %d/%d = %d/%d = %d/%d = {%.3f ° %.3f = %.3f)',
          [ A.Numerateur, A.Denominateur,
            B.Numerateur, B.Denominateur,
            R.Numerateur, R.Denominateur,
            S.Numerateur, S.Denominateur,
            Float(A), Float(B), Float(R)]
        )
      );
     
      R := A * B;
      S := round(R);
      ListBox1.Items.Add(
        format(
          '%d/%d * %d/%d = %d/%d = %d/%d = {%.3f ° %.3f = %.3f)',
          [ A.Numerateur, A.Denominateur,
            B.Numerateur, B.Denominateur,
            R.Numerateur, R.Denominateur,
            S.Numerateur, S.Denominateur,
            Float(A), Float(B), Float(R)]
        )
      );
    end;

    Exemple avec RECOP non définit :

    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
     
    procedure TForm13.Button1Click(Sender: TObject);
    var A, B, R, S: TFraction;
    begin
      A := FractionCreate(3,9);
      B := FractionCreate(4,11);
     
      R := FractionAdd(A,B);
      S := FractionSimplify(R);
      ListBox1.Items.Add(
        format(
          '%d/%d + %d/%d = %d/%d = %d/%d = {%.3f ° %.3f = %.3f)',
          [ A.Numerateur, A.Denominateur,
            B.Numerateur, B.Denominateur,
            R.Numerateur, R.Denominateur,
            S.Numerateur, S.Denominateur,
            FractionToFloat(A), FractionToFloat(B), FractionToFloat(R)]
        )
      );
     
      R := FractionSubtract(A,B);
      S := FractionSimplify(R);
      ListBox1.Items.Add(
        format(
          '%d/%d - %d/%d = %d/%d = %d/%d = {%.3f ° %.3f = %.3f)',
          [ A.Numerateur, A.Denominateur,
            B.Numerateur, B.Denominateur,
            R.Numerateur, R.Denominateur,
            S.Numerateur, S.Denominateur,
            FractionToFloat(A), FractionToFloat(B), FractionToFloat(R)]
        )
      );
     
      R := FractionMultiply(A,B);
      S := FractionSimplify(R);
      ListBox1.Items.Add(
        format(
          '%d/%d * %d/%d = %d/%d = %d/%d = {%.3f ° %.3f = %.3f)',
          [ A.Numerateur, A.Denominateur,
            B.Numerateur, B.Denominateur,
            R.Numerateur, R.Denominateur,
            S.Numerateur, S.Denominateur,
            FractionToFloat(A), FractionToFloat(B), FractionToFloat(R)]
        )
      );
    end;

  6. #6
    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
    jolie gymnastique

  7. #7
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 085
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 085
    Points : 15 507
    Points
    15 507
    Billets dans le blog
    9
    Par défaut
    J'ai bien aimé ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {$IFDEF RECOP}class operator TFraction.{$ELSE}function Fraction{$ENDIF}Add(A, B: TFraction): TFraction;
    Je m'en resservirai quelque part.

    "RECOP", ça veut dire quoi ?

  8. #8
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    Je vais expliquer :


    RECOP est la directive pour "RECORD OPERATOR"
    Elle est conditionnée par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    {$IF RTLVersion >= 18.0}
      {$DEFINE RECOP}
    {$IFEND}
    Si la version de la RTL est supérieure ou égale à D2007, RECOP est définie.
    (je crois que D2007 supporte les opérateur).

    Si cela ne fontionne pas sur D2007 il faudrait corrigé pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    {$IF RTLVersion >= 20.0} { Delphi 2009 RTLVersion } 
      {$DEFINE RECOP}
    {$IFEND}
    D'habitude j'utilise "NGEN" ou "NG" pour dire que je suis sur un compilateur nouvelle génération.
    comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {$DEFINE OG}
    {$IF RTLVersion >= 20.0}
      {$DEFINE NG}
      {$UNDEF OG}
    {$IFEND}


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {$IFDEF RECOP}class operator TFraction.{$ELSE}function Fraction{$ENDIF}Add(A, B: TFraction): TFraction;
    Si RECOP est définie (donc si la RTLVersion et > 18) on déclare l'entête sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class operator TFraction.Add()
    Sinon on déclare l'entête d'une fonction standard
    concrètement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ["class operator TFraction."|"function Fraction"]+"Add(*):*;"
    Le code de fonction étant le même pour l’opérateur et pour la fonction, on ne conditionne que l'entête

    l'opérateur Explicit est l'opérateur utilisé quand on assigne une valeur avec :=

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    explicit(TPoint): string
    correspond à l'assignation dans les contextes suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    (string) := (TPoint)
    (TCaption) := (TPoint)
    (TFileName) := (TPoint)
    exemple :
    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
     
    type
      TPoint = record
        X, Y: integer;
        class operator Explicit(A: TPoint): string;
      end;
     
    class operator TPoint.Explicit(A:TPoint): string;
    begin
      result := format('%d x %d',[A.X, A.Y]);
    end;
     
    procedure TForm1.Form1MouseMove(Sender: TObject; X, Y: integer);
    var P : TPoint;
    begin
      P.X := X;
      P.Y := Y;
      Label1.Caption := P; // "X x Y"
    end;
    Implicit est l'opérateur de "transtypage" quand on englobe un element par le type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (string context)( (type(element)) )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Label1.Caption := 'Coordonnées : ' + TPoint([X,Y])
    qui devra s'écrire comme ceci :
    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
     
      TPoint = record
        X, Y: integer;
        class operator Explicit(A: TPoint): string;
        class operator Implicit(A: array of integer): TPoint;
      end;
     
    class operator TPoint.Explicit(A:TPoint): string;
    begin
      result := format('%d x %d',[A.X, A.Y]);
    end;
     
    class operator TPoint.Implicit(A:array of integer): TPoint;
    begin
      assert(Length(A) <> 2, 'A poop bug appears in yur program, you suck.');
      result.X := A[0];
      result.Y := A[1];
    end;
    ce qui donnera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'Coordonnées : ' + TPoint.Explicit(TPoint.Implicit([X, Y])):string;

    Ce qui est sympa avec ça, c'est qu'on est pas tenus de respecter strictement l'operateur.

    Par exemple dans TFraction, l'operateur Round, n’arrondis par la fraction réelle mais simplifie la fraction

    TFraction(2/4).Round ==> TFraction(1/2)
    TFraction(20/1000).Round ==> TFraction(1/50)
    TFraction(256/80).Round ==> TFraction(16/5)

    Pourtant on s’attendrait à ce que Round arrondisse la fraction (résultat réel)

    TFraction(2/4).Round == 0.5 =/=> 0
    TFraction(20/1000).Round == 0.02 =/=> 0
    TFraction(256/80).Round == 3.2 =/=> 3

    Mais dans ce cas, il serait inutile d'utiliser cette valeur arrondie.


    Théoriquement, il n'y a pas de limite à l'utilisation/détournement des opérateurs. On pourrait très bien créer un type TString pour mapper String et ajouter des fonctionnalité aux chaines.

    - permettrais de supprimer les sous-chaines de la chaine
    * permettrais de dupliquer N fois la chaine
    / permettrais de faire une comparaison ou autre
    shl et shr de supprimer N caractère au début ou à la fin de la chaine
    on pourrais imaginer d'autre comportement pour And, Or, Xor etc.

    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
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
     
    type
      TString = record
        value: string;
      public
        // (TString) := TString.Create('Hello world !');
        class function create(S: string): TString; static;
     
        // (integer) := (TString).length;
        function Length: integer; overload;
        // (integer) := TString.Length('Hello')
        class function Length(S: string): integer; overload; static;
     
        // (String|TString) := (TString).LowerCase
        function LowerCase: string; overload;
        // (String|TString) := TString.LowerCase('Hello');
        class function LowerCase(S: string): string; overload; static;
     
        // (String|TString) := (TString).UpperCase
        function UpperCase: string; overload;
        // (String|TString) := TString.UpperCase('Hello');
        class function UpperCase(S: string): string; overload; static;
     
        // if (TString).Size = 10 then isWide
        function Size: integer; overload;
        // if TString.Size('Hello') = 10 then isWide
        class function Size(S: string): integer; overload; static;
     
        // String et TString utilisation transparente
          // (TStrings) := (String)
        class operator Explicit(A: string): TString;
          // (String) := (TString)
        class operator Explicit(A: TString): string;
          // TString((String))
        class operator Implicit(A: string): TString;
          // String((TString))
        class operator Implicit(A: TString): string;
     
        // renvois un TString avec Setlength(A) sur value
        // (TString) := 5;
        // (TString).Value = #0#0#0#0#0
        class operator Explicit(A: integer): TString;
     
        // renvois Length de TString
        // (integer) := (TString)
        class operator Explicit(A: TString): integer;
     
        // duplique B, A fois
        // (Tstring) := 5 * 'Ha';
        // resultat = 'HaHaHaHaHa'
        class operator Multiply(A: integer; B: TString): TString;
     
        // supprime le caractère A de la chaine B
        // (Tstring) := 'h' - TString('le hiboux etait à l''hopital car il etait tombé du chêne');
        // resultat = 'le iboux etait à l''opital car il etait tombé du cêne'
        class operator Subtract(A: char; B: TString): TString;
     
        // compte le nombre d'occurence du caractère A dans la chaine B
        // (integer) := 'h' and TString('le hiboux etait à l''hopital car il etait tombé du chêne')
        // resultat = 3
        class operator LogicalAnd(A: char; B: TString): integer;
     
      end;
     
    { TString }
     
    class function TString.create(S: string): TString;
    begin
      result.Value := S;
    end;
     
    function TString.Length: integer;
    begin
      result := length(Value);
    end;
     
    class operator TString.Explicit(A: string): TString;
    begin
      result.value := A;
    end;
     
    class operator TString.Explicit(A: TString): string;
    begin
      result := A.value;
    end;
     
    class operator TString.Implicit(A: string): TString;
    begin
      result.value := A;
    end;
     
    class operator TString.Implicit(A: TString): string;
    begin
      result := A.value;
    end;
     
    class function TString.Length(S: string): integer;
    begin
      result := length(S);
    end;
     
    function TString.LowerCase: string;
    begin
      result := lowercase(Value);
    end;
     
    class operator TString.LogicalAnd(A: char; B: TString): integer;
    var X: integer;
    begin
      result := 0;
      for X := 1 to B.Length do
        if B.value[X] = A then
          inc(result);
    end;
     
    class function TString.LowerCase(S: string): string;
    begin
      result := lowerCase(S);
    end;
     
    class operator TString.Multiply(A: integer; B: TString): TString;
    var X: integer;
    begin
      for X := 0 to A do
        result.value := result.value + B;
    end;
     
    function TString.Size: integer;
    begin
      result := Length(Value) * SizeOf(char);
    end;
     
    class function TString.Size(S: string): integer;
    begin
      result := Length(S) * SizeOf(char);
    end;
     
    class operator TString.Subtract(A: char; B: TString): TString;
    var X: integer;
    begin
      for X := 1 to B.Length do
        if B.value[X] <> A then
          result.value := result.value + B.value[X];
    end;
     
    function TString.UpperCase: string;
    begin
      result := upperCase(Value);
    end;
     
    class function TString.UpperCase(S: string): string;
    begin
      result := upperCase(S);
    end;
     
    class operator TString.Explicit(A: integer): TString;
    begin
      result.value := '';
      setLength(result.value, A);
      fillChar(result.value, A, #0);
    end;
     
    class operator TString.Explicit(A: TString): integer;
    begin
      result := A.Length;
    end;

    Et comme je suis fou, voila un exemple de déclaration complète avec TRect !

    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
     
    type
      PRect = ^TRect;
      TRect = record
      public
        class function Create(const aLeft, aTop, aRight, aBottom: integer): TRect; static;
     
        procedure SetTo(const aLeft, aTop, aRight, aBottom: integer);
        function IsEmpty: boolean;
     
        procedure Inflate(const dX, dY: integer);
        procedure Deflate(const dX, dY: integer);
        procedure Offset(const oX, oY: integer);
        function Width: integer;
        function Height: integer;
        function Surface: single;
     
        class operator Implicit(A: TRect): string;
        class operator Implicit(A: TRect): TSize;
        class operator Implicit(A: TRect): TPoint;
        class operator Add(A, B: TRect): TRect;
        class operator Subtract(A, B: TRect): TRect;
        class operator Equal(A, B: TRect): boolean;
        class operator NotEqual(A, B: TRect): boolean;
      public
        case Integer of
          0: (Left, Top, Right, Bottom: integer);
          1: (TopLeft, BottomRight: TPoint);
      end;
      TRectList = TList<TRect>;
     
    const
      SizeOfTRect = SizeOf(TRect);
    a noter que dans D2009 et + les records sont compatible avec de nombreux éléments :

    const, private, public, protected, class function, class procedure, function, procedure, overload, satic, class operator, property, case of ...

    On peux donc créer des RichRecord comme si il s'agissait d'objets 100% dynamique dont on ne se soucie pas de la création libération.

    Autre point intéressant, avec les Property dans un record, on peu faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type
      TAI = record
      private
        fInts : array[0..3] of integer;
        procedure setI(index, value: integer);
        function getI(index: integer): integer;
      public
        property A: integer read fInts[0] write fInts[0];
        property B: integer read fInts[1] write fInts[1];
        property C: integer read fInts[2] write fInts[2];
        property D: integer read fInts[3] write fInts[3];
        property Ints[index: integer] : integer read getI write setI;
      end;
    Notez la déclaration des propriétés A,B,C,D, on accède directement a fInts sans passer par des méthodes set/get contrairement à Ints ou à cette déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    property A: integer index 0 read getI write setI;

Discussions similaires

  1. [TPW] Opérations simples sur les fractions
    Par forum dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 16/11/2011, 20h43
  2. Application d'opération sur les fractions : erreurs de compilation
    Par int828 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 10/10/2009, 14h09
  3. Opérations sur les matrices...
    Par aokiseiichiro dans le forum C
    Réponses: 32
    Dernier message: 28/07/2005, 17h10
  4. opérations sur les bits d'un byte
    Par petitours dans le forum C++Builder
    Réponses: 4
    Dernier message: 10/02/2004, 20h42
  5. opérations sur les dates
    Par coucoucmoi dans le forum Débuter
    Réponses: 2
    Dernier message: 12/08/2003, 11h45

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