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 :

INT128 et UINT128


Sujet :

Delphi

  1. #1
    Membre éprouvé Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    796
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2005
    Messages : 796
    Points : 1 044
    Points
    1 044
    Par défaut INT128 et UINT128
    Bonjour,

    Pour un besoin imposé très spécifique j’aurais besoin des types INT128 et UINT128, mais les rares codes que j’ai trouvé sont pas simple d’utilisation pour mon Delphi 11.2 !

    Quelqu’un a déjà eu à travaillé avec ce type, et si oui, quelle classe ou source vous avez utilisés ?

    Merci d’avance de vos retours ?

  2. #2
    Membre actif
    Homme Profil pro
    libre
    Inscrit en
    Mai 2024
    Messages
    112
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Mai 2024
    Messages : 112
    Points : 206
    Points
    206
    Par défaut
    La bibliothèque Clipper version 1 contient un petit support pour int128 uniquement pour les opérations basiques addition, soustraction, multiplication et division

    https://github.com/skyrpex/clipper/b...ipper.pas#L658

  3. #3
    Membre éprouvé Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    796
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2005
    Messages : 796
    Points : 1 044
    Points
    1 044
    Par défaut
    Merci, je vais regarder !

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 553
    Points : 25 133
    Points
    25 133
    Par défaut
    Tu peux aussi utiliser la lib BigInt : https://github.com/rvelthuis/DelphiB...igIntegers.pas


    Je me suis amusé pour Triangle de Pascal a coder l'addition d'un BigInt, totalement par tâtonnement

    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
    type
      UIntBig = record
      private
        type TInternalItem = UInt64;
        type TInternalData = array of TInternalItem;
        var Data: TInternalData;
        const BitOrder = 63-16; 
        const BigBit = TInternalItem(1) shl BitOrder - 1; // 7FFF FFFF FFFF en 47 soit 63-16
        const ToStringStep = 4;
      public
        class function Create(AValue: TInternalItem = 0): UIntBig; static;
     
        function Add(Other: UIntBig): UIntBig;
        function ToString(): string;
      end;
     
    procedure TrianglePascal100(AStrings: TStrings = nil);
     
      procedure ToStrings(const I: array of UIntBig);
      var
        J: Integer;
        S: string;
      begin
        if Assigned(AStrings) then
        begin
          S := I[Low(I)].ToString();
          for J := Succ(Low(I)) to High(I) do
            S := S + ' ' +  I[J].ToString();
          AStrings.Add(S);
        end;
      end;
     
    var
      Curr, Next: array of UIntBig;
      I, J: Integer;
    begin
      // Ligne 1 c'est 1
      AStrings.Add('1');
      // Ligne 2 c'est 1 1 - exprimé par le tableau ci dessous
      SetLength(Curr, 2);
      Curr[0] := UIntBig.Create(1);
      Curr[1] := UIntBig.Create(1);
      ToStrings(Curr);
     
      // Ligne 3 c'est 1 2 1 - c'est lui que l'on cherche à calculer
      for I := 3 to 200 do
      begin
        SetLength(Next, Length(Curr) + 1);
        Next[0] := Curr[0];
        for J := Succ(Low(Curr)) to High(Curr) do
          Next[J] := Curr[J - 1].Add(Curr[J]);
     
        Next[High(Next)] := Curr[High(Curr)];
        Curr := Next;
        ToStrings(Curr);
      end;
      // 100ème donc avec un indice en base 0 c'est le 99, reflexe habituel avec un tableau
      AStrings.Add('100ème');
      AStrings.Add(Curr[99].ToString());
    end;
     
    { UIntBig }
     
    //------------------------------------------------------------------------------
    function UIntBig.Add(Other: UIntBig): UIntBig;
    var
      I, L: Integer;
      Sum, Carry: TInternalItem;
    begin
       if (Length(Self.Data) > 0) and (Length(Other.Data) > 0) then
       begin
         L := Max(Length(Self.Data), Length(Other.Data));
         SetLength(Result.Data, L);
         Carry := 0;
         for I := 0 to L - 1 do
         begin
           Sum := Carry;
           if I <= High(Self.Data) then
             Sum := Sum + Self.Data[I];
           if I <= High(Other.Data) then
             Sum := Sum + Other.Data[I];
     
           (*
           if Sum > BigBit then
             Beep();
           *)
     
           Result.Data[I] := Sum and BigBit;
           Carry := Sum shr BitOrder;
         end;
         if Carry > 0 then
         begin
           SetLength(Result.Data, L + 1);
           Result.Data[L] := Carry;
         end;
       end
       else if Length(Self.Data) > 0 then
         Result := Self
       else
         Result := Other;
    end;
     
    //------------------------------------------------------------------------------
    class function UIntBig.Create(AValue: TInternalItem = 0): UIntBig;
    var
      L: Integer;
      Carry: TInternalItem;
    begin
      Carry := 0;
     
      L := 1;
      SetLength(Result.Data, L);
      if AValue > 0 then
      begin
        Result.Data[0] := AValue and BigBit;
        Carry := AValue shr BitOrder;
        if Carry > 0 then
        begin
         SetLength(Result.Data, L + 1);
         Result.Data[L] := Carry;
        end;
      end
      else
        Result.Data[0] := 0;
    end;
     
    //------------------------------------------------------------------------------
    function UIntBig.ToString(): string;
    var
      I: Integer;
      Temp: TInternalData;
      Sum, Carry, Step: TInternalItem;
    begin
      if Length(Self.Data) > 0 then
      begin
        Temp := Copy(Self.Data);
        Result := '';
        Step := Trunc(IntPower(10, ToStringStep));
        while (Length(Temp) > 0) and (Temp[0] > 0) do
        begin
          Carry := 0;
          for I := High(Temp) downto Low(Temp) do
          begin
            Sum := Carry shl BitOrder;
            Sum := Sum or Temp[I];
            DivMod(Sum, Step, Temp[I], Carry);
            //Temp[I] := Sum div Step;
            //Carry := Sum mod Step;
          end;
          if Temp[High(Temp)] = 0 then
            SetLength(Temp, High(Temp));
          if Length(Temp) > 0 then
            Result := Format('%.*d', [ToStringStep, Carry]) + Result
          else
            Result := Format('%d', [Carry]) + Result;
        end;
      end
      else
        Result := '0';
    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
    Expert confirmé Avatar de sergio_is_back
    Homme Profil pro
    Consultant informatique industrielle, développeur tout-terrain
    Inscrit en
    Juin 2004
    Messages
    1 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique industrielle, développeur tout-terrain
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 127
    Points : 5 809
    Points
    5 809
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Tu peux aussi utiliser la lib BigInt : https://github.com/rvelthuis/DelphiB...igIntegers.pas
    Oui, je plussoie, BigIntegers est une bonne solution, je l'ai déjà utilisé dans un projet

  6. #6
    Membre éprouvé Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    796
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2005
    Messages : 796
    Points : 1 044
    Points
    1 044
    Par défaut
    On peux mixer bigint et les opérations mathématiques de base avec des cardinaux et autre uint64 voir de simple integer ?

    [MAJ]

    Je vient de voir les implicites et les explicites dans la classe, j’espére juste que la compilation en monde 64 bits ne me crée pas de mauvaise surprise

  7. #7
    Expert confirmé Avatar de sergio_is_back
    Homme Profil pro
    Consultant informatique industrielle, développeur tout-terrain
    Inscrit en
    Juin 2004
    Messages
    1 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique industrielle, développeur tout-terrain
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 127
    Points : 5 809
    Points
    5 809
    Par défaut
    Je te confirme que le mode 64 bits est pleinement supporté

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

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