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

Lazarus Pascal Discussion :

Meilleure approche pour une valeur sur 12 bits [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre actif Avatar de der§en
    Homme Profil pro
    Meaux
    Inscrit en
    septembre 2005
    Messages
    359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Meaux
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2005
    Messages : 359
    Points : 291
    Points
    291
    Par défaut Meilleure approche pour une valeur sur 12 bits
    Bonjour,

    Quelle serait pour vous la meilleure solution pour coder dans un WORD une valeur non-signée sur 12 bits complétée par une autre sur 4 bits ?

    Le tout pouvant être utilisé dans des tableaux !

    Quelle serait votre approche ?

  2. #2
    Rédacteur/Modérateur

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

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 3 517
    Points : 12 280
    Points
    12 280
    Billets dans le blog
    8
    Par défaut
    Bonjour !

    Je ne sais pas si c'est la meilleure solution, mais personnellement j'aurais fait 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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    {$ASSERTIONS ON}
     
    type
      T1 = 0..4095;
      T2 = 0..15;
     
    function Encode(const v1: T1; const v2: T2): word;
    begin
      result := (v1 shl 4) or v2; 
    end;
     
    procedure Decode(const w: word; out v1: T1; out v2: T2);
    begin
      v1 := w shr 4;
      v2 := w and 15; 
    end;
     
    var
      w: word;
      v1: T1;
      v2: T2;
     
    begin
      Assert(%1111111111111111 = 65535);
      Assert(%111111111111 = 4095);
      Assert(%1111 = 15);
     
      w := Encode(4095, 15);
      Assert(w = 65535);
     
      Decode(w, v1, v2);
      Assert(v1 = 4095);
      Assert(v2 = 15);
     
      Randomize;
      v1 := Random(4096);
      v2 := Random(16);
      WriteLn(v1);
      WriteLn(v2);
      w := Encode(v1, v2);
      Decode(w, v1, v2);
      WriteLn(v1);
      WriteLn(v2);
    end.

  3. #3
    Membre confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    mai 2013
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : mai 2013
    Messages : 88
    Points : 519
    Points
    519
    Par défaut Entassés
    Bonjour,

    Il existe aussi des enregistrements qui proposent la compression binaire comme cela si je ne fais pas erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TStrange = bitpacked record 
      T1 = 0..4095;
      T2 = 0..15;
    end;
    Mais je suis loin d'être sûr que c'est pertinent en efficacité comme en lisibilité (le moindre usage demandera des transtypages un peu partout que la solution de Roland masque).

    Salutations.
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  4. #4
    Membre actif Avatar de der§en
    Homme Profil pro
    Meaux
    Inscrit en
    septembre 2005
    Messages
    359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Meaux
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2005
    Messages : 359
    Points : 291
    Points
    291
    Par défaut
    Pourquoi, il faudrais des transtypages partout, cette affirmation me laisse un peu dubitatif...

    je vais faire des essais pour comprendre ta remarque.

  5. #5
    Membre confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    mai 2013
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : mai 2013
    Messages : 88
    Points : 519
    Points
    519
    Par défaut Casting et transtypage
    Bonjour,

    Normalement Pascal est un langage typé et devrait interdire un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
       i : Cardinal:   // ou Word...
       Strange : TStrange;
    //...
    i := Strange.T1;
    et demander :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i := Cardinal(Strange.T1);
    A vérifier le degré de tolérance du compilateur FreePascal.

    Il y a aussi la possibilité de déclarer des types TCard12 = 0..4095; et TNibble = 0..15; mais cela ne recule le problème que d'un cran car le reste du programme utilisera certainement d'autre types plus communs.

    Sur ce plan, C et C++ paraissent plus souples avec leurs champs binaires typés.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

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

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

    Informations forums :
    Inscription : mars 2005
    Messages : 3 355
    Points : 9 797
    Points
    9 797
    Billets dans le blog
    6
    Par défaut
    Il est possible d'affecter un Byte à un Int64 sans trranstypage, pourquoi pas un sous-ensemble à un Word ? A tester en tout cas.

    Autre voie possible, celle des helpers, peut-être plus "naturelle" ?
    Delphi 5 Pro - Delphi 10.3.2 Rio 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
    Membre actif Avatar de der§en
    Homme Profil pro
    Meaux
    Inscrit en
    septembre 2005
    Messages
    359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Meaux
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2005
    Messages : 359
    Points : 291
    Points
    291
    Par défaut
    Et quelque chose comme cela ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    TStrange = bitpacked record
      case integer of
        0:
           T0: WORD;
        1:
           T1 = 0..4095;
           T2 = 0..15;
    end;
    
    Cela ne pourrais pas éviter le transtypages ?

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

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

    Informations forums :
    Inscription : mars 2005
    Messages : 3 355
    Points : 9 797
    Points
    9 797
    Billets dans le blog
    6
    Par défaut
    Bonsoir,
    Voici un test avec les type helpers :
    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
    unit Unit1;
     
    {$mode objfpc}{$H+}
    {$MODESWITCH TYPEHELPERS} // indispensable !
     
    interface
     
    uses
      Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
     
    type
      TDuo = Word;
      TDuoHelper = type helper(TWordHelper) for TDuo
        function ToTwelveHighBitsValue: Word;
        function ToFourLowBitsValue: Word;
        function SetTwelveHighBitsValue(aValue: Word): Boolean;
        function SetFourLowBitsValue(aValue: Word): Boolean;
      end;
      { TForm1 }
     
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
     
      public
     
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.frm}
     
    { TForm1 }
     
    function TDuoHelper.ToTwelveHighBitsValue: Word;
    begin
      Result := self shr 4;
    end;
     
    function TDuoHelper.ToFourLowBitsValue: Word;
    begin
      Result := self and $F;
    end;
     
    function TDuoHelper.SetTwelveHighBitsValue(aValue: Word): Boolean;
    begin
      Result := aValue < $1000;
      if Result then
        self := ( self and $F ) or ( aValue shl 4 );
    end;
     
    function TDuoHelper.SetFourLowBitsValue(aValue: Word): Boolean;
    begin
      Result := aValue < $10;
      if Result then
        self := ( self and $FFF0 ) or aValue;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    const
      cste = $10;
    var
      Duo: TDuo;
      w: Word;
    begin
      w := cste;
      Duo := w;
      ShowMessage(IntToStr(Duo.ToTwelveHighBitsValue));
      Dec(Duo);
      ShowMessage(IntToStr(Duo.ToFourLowBitsValue));
    end;
     
    end.
    On doit pouvoir tout faire : l'affectation comme un Word, un Encode simultané des 2 parties comme dans l'exemple de Roland, l'affectation différenciée (en clippant ou pas), etc.

    [EDIT] Pour l'approche BitPacked, en lisant ceci, l'utilisation me semble au moins aussi complexe.
    Delphi 5 Pro - Delphi 10.3.2 Rio 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 !

  9. #9
    Membre actif Avatar de der§en
    Homme Profil pro
    Meaux
    Inscrit en
    septembre 2005
    Messages
    359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Meaux
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2005
    Messages : 359
    Points : 291
    Points
    291
    Par défaut
    Ceci fonctionne et je n'ai pas encore vu de désagréments.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      TDsTest = bitpacked record
        case integer of
        0: (TOUT: Word);
        1: (GRAND: 0..4095;
            PETIT: 0..15);
      End;
    Merci a vous pour l'aide apporté...


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

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

    Informations forums :
    Inscription : mars 2005
    Messages : 3 355
    Points : 9 797
    Points
    9 797
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Effectivement, pas d'inconvénient apparent (NB : compte tenu de l'ordre de déclaration, le GRAND occupe ici les bits de poids faible du WORD).

    Avec cette formule, pas de contrôle du dépassement par un setter : on affecte par exemple Valeur mod 16 au PETIT quand on fait DsTest.PETIT := valeur;, ce qui est le comportement standard de FPC quand on affecte une valeur plus grande à une variable entière non signée.
    Delphi 5 Pro - Delphi 10.3.2 Rio 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 !

  11. #11
    Membre actif Avatar de der§en
    Homme Profil pro
    Meaux
    Inscrit en
    septembre 2005
    Messages
    359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Meaux
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2005
    Messages : 359
    Points : 291
    Points
    291
    Par défaut
    J'ai bien fait ce test la mais le compilateur de veux pas de mon "case" a cette endroits, j'ai un bel "Syntax error, ':' expected but 'CASE' found :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      TDsTest = bitpacked record
      private
        case integer of
          0: (fTOUT: Word);
          1: (fGRAND: 0..4095;
              fPETIT: 0..15);
        procedure SetTOUT(AValue: integer);
        procedure SetGRAND(AValue: integer);
        procedure SetPETIT(AValue: integer);
      public
        property TOUT:  word read fTOUT write SetTOUT;
        property GRAND: 0..4095 read fGRAND write SetGRAND;
        property PETIT: 0..15 read fPETIT write SetPETIT;
      End;

  12. #12
    Membre expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    1 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : septembre 2015
    Messages : 1 153
    Points : 3 015
    Points
    3 015
    Billets dans le blog
    2
    Par défaut
    Salut

    Essayes 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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    {$MODESWITCH ADVANCEDRECORDS}
     
    Type
      TBigBit = 0..4095;
      TSmallBit = 0..15;  
      TDsTest = bitpacked record
      private
      public
          procedure Create(Value : Word); overload;
          procedure Create(Value : TBigBit); overload;
          procedure Create(Value : TSmallBit); overload;
          procedure Create(BigValue : TBigBit; SmallValue : TSmallBit); overload;
     
          case integer of // Doit-être dans la partie public, sinon il faut declarer dans UNE CLASSE (je crois que ce n'est pas faisable dans un record) un "sous-type" dans private et accéder aux valeurs avec des setter/getter dans les propriétés
            0: (TOUT: Word);
            1: (GRAND: TBigBit;
                 PETIT: TSmallBit);
        End;
     
    Implementation
     
    Procedure Tdstest.Create(Value : Word);
    Begin
      Self.Tout := Value;
    End;
     
    Procedure Tdstest.Create(Value : Tbigbit);
    Begin
      Self.Grand := Value;
    End;
     
    Procedure Tdstest.Create(Value : Tsmallbit);
    Begin
      Self.Petit := Value;
    End;
     
    Procedure Tdstest.Create(Bigvalue : Tbigbit; Smallvalue : Tsmallbit);
    Begin
      Self.Grand := BigValue;
      Self.Petit := SmallValue;
    End;
    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 05/01/2014, 23h32
  2. [MVVM] quelle est la meilleure approche pour afficher une liste d'images ?
    Par SIC83 dans le forum Silverlight
    Réponses: 0
    Dernier message: 21/10/2012, 12h50
  3. [Toutes versions] Formule pour recuperer une valeur sur un autre fichier Excel
    Par bonilla dans le forum Excel
    Réponses: 2
    Dernier message: 26/06/2012, 12h19
  4. Réponses: 3
    Dernier message: 04/01/2012, 10h00
  5. Réponses: 1
    Dernier message: 21/02/2010, 09h42

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