Sign in Join
Wiki copytemporary

Bit manipulation/fr: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-\
2-\
3-
41## Opération masquées
52
63Ceci est une approche bas niveau basique pour manier les manipulation de bit. Le principale avantage est que les opérations peuvent être réalisées sur un groupes de bits en une seule fois. Mais l'utilisateur doit faire face à ces opérations par lui-même. Un autre problème est l'intervalle maximal des valeurs utilisées dans les paramètres de fonction. Il faut donc séparer les implémentations de chaque type ordinal pour de meilleures performances (contrairement à ce qui peut être fait en C en utilisant le préprocesseur).
74
85(NdT : une solution peut résider dans l'emploi de fonctions génériques, non développées ici.)
96
107``` pascal
118procedure ClearBit(var Value: QWord; Index: Byte);
129begin
1310 Value := Value and ((QWord(1) shl Index) xor High(QWord));
1411end;
1512
1613procedure SetBit(var Value: QWord; Index: Byte);
1714begin
1815 Value:= Value or (QWord(1) shl Index);
1916end;
2017
2118procedure PutBit(var Value: QWord; Index: Byte; State: Boolean);
2219begin
2320 Value := (Value and ((QWord(1) shl Index) xor High(QWord))) or (QWord(State) shl Index);
2421end;
2522
2623function GetBit(Value: QWord; Index: Byte): Boolean;
2724begin
2825 Result := ((Value shr Index) and 1) = 1;
2926end;
3027```
3128
3229## Enregistrement bit-paqueté (Bitpacked)
3330
3431FPC a une extension utile qui permet non seulement le paquetage des enregistrements par octet mais aussi le paquetage par bit. Ceci permet de définir non seulement des structures de bits en utilisant le type booléen ou des intervalles 0..1 mais aussi des champs à n états ou n-bits dans des enregistrements p.ex. le type intervalle 0..3 pour 2 bits. L'utilisation conjointe d'une telle structure de bits et d'un enregistrement avec variante permet d'accéder à la mémoire soit par octet soit par bit individuel.
3532
3633``` pascal
3734TByteBits = bitpacked record
3835 Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7: Boolean;
3936end;
4037
4138TByteEx = packed record
4239 case Integer of
4340 0: (ByteAccess: Byte);
4441 1: (BitAccess: TByteBits);
4542end;
4643
4744TSomeBitLevelStructure = bitpacked record
4845 OneBit: 0..1;
4946 TwoBits: 0..3;
5047 FourBits: 0..15;
5148 EightBits: 0..255
5249end;
5350```
5451
5552NB : on accède au bit via des identificateurs.
5653
5754Le paquetage par bit peut être contrôlé en utilisant la directive [\$BITPACKING](http://www.freepascal.org/docs-html/prog/progsu6.html).
5855
5956## Type ensemble
6057
6158Parce que les ensembles sont basiquement des tableaux de tous les états qui sont des types booléens, il est donc possible de les utiliser comme tableaux de bits. Mais cela nécessite l'emploi de la directive de compilation [\$PACKENUM](http://www.freepascal.org/docs-html/prog/progsu57.html#x63-620001.1.57) pour modifier la taille de l'ensemble. Il y aussi certaines limitations sur la taille maximale d'un ensemble.
6259
6360``` pascal
6461{$packset 1}
6562{$packenum 1}
6663
6764type
6865 TByteBits = set of (Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7);
6966```
7067
7168## TBits
7269
7370Cette classe fait partie de la bibliothèque RTL de FPC, contenue dans l'unité Classes et s'emploie de manière similaire à celle de Delphi. Elle fournit seulement quelques méthodes pour les manipulations de bits.
7471
7572``` pascal
7673 TBits = class(TObject)
7774 public
7875 constructor Create(TheSize : longint = 0); virtual;
7976 destructor Destroy; override;
8077 function GetFSize : longint;
8178 procedure SetOn(Bit : longint);
8279 procedure Clear(Bit : longint);
8380 procedure Clearall;
8481 procedure AndBits(BitSet : TBits);
8582 procedure OrBits(BitSet : TBits);
8683 procedure XorBits(BitSet : TBits);
8784 procedure NotBits(BitSet : TBits);
8885 function Get(Bit : longint) : boolean;
8986 procedure Grow(NBit : longint);
9087 function Equals(Obj : TObject): Boolean; override; overload;
9188 function Equals(BitSet : TBits) : Boolean; overload;
9289 procedure SetIndex(Index : longint);
9390 function FindFirstBit(State : boolean) : longint;
9491 function FindNextBit : longint;
9592 function FindPrevBit : longint;
9693
9794 { functions and properties to match TBits class }
9895 function OpenBit: longint;
9996 property Bits[Bit: longint]: Boolean read get write SetBit; default;
10097 property Size: longint read FBSize write setSize;
10198 end;
10299```
103100
104101NB :
105102
106103- Pas de limitation de taille comme avec les ensembles,
107104- les bits sont accessibles uniquement de manière ordinale.
108105
109106## Propriété enregistrement et valeur index
110107
111108Une autre implémentation intéressante des structures alignées sur les bits peur être utilisée avec la capacité des enregistrements avancés (FPC 2.6.0+). Pour toutes les propriétés, vous devez utiliser un accesseur en écriture et un en lecture qui peuvent gérer les manipulations générales des bits et définir l'index qui est transmis à ces méthodes. Pour plus d'informations, reportez-vous aux [propriétés indexées](http://www.freepascal.org/docs-html/ref/refsu31.html). Parce que l'index de propriété est unique, il a été divisé en deux paramètres pour décrire, la position et la taille de la valeur de bit. Dans le cas de l'exemple suivant, le décalage peut être de 0..255 et la taille de la valeur 0..255 bits. Un autre problème est que vous devez vous assurer que les composants définis dans la structure ne se chevaucheront pas.
112109
113110``` pascal
114111{$mode delphi}
115112
116113 TSomeBitStructure = record
117114 private
118115 RawData: Word;
119116 function GetBits(const AIndex: Integer): Integer; inline;
120117 procedure SetBits(const AIndex: Integer; const AValue: Integer); inline;
121118 public
122119 // High byte of index offset, low byte of index is bit count
123120 property OneBit: Integer index $0001 read GetBits write SetBits;
124121 property TwoBits: Integer index $0102 read GetBits write SetBits;
125122 property FourBits: Integer index $0304 read GetBits write SetBits;
126123 property EightBits: Integer index $0708 read GetBits write SetBits;
127124 end;
128125
129126{$OPTIMIZATION ON}
130127{$OVERFLOWCHECKS OFF}
131128function TSomeBitStructure.GetBits(const AIndex: Integer): Integer;
132129var
133130 Offset: Integer;
134131 BitCount: Integer;
135132 Mask: Integer;
136133begin
137134 BitCount := AIndex and $FF;
138135 Offset := AIndex shr 8;
139136 Mask := ((1 shl BitCount) - 1);
140137 Result := (RawData shr Offset) and Mask;
141138end;
142139
143140procedure TSomeBitStructure.SetBits(const AIndex: Integer; const AValue: Integer);
144141var
145142 Offset: Integer;
146143 BitCount: Integer;
147144 Mask: Integer;
148145begin
149146 BitCount := AIndex and $FF;
150147 Offset := AIndex shr 8;
151148 Mask := ((1 shl BitCount) - 1);
152149 Assert(aValue <= Mask);
153150 RawData := (RawData and (not (Mask shl Offset))) or (AValue shl Offset);
154151end;
155152```
156153
157154---
158155*From the Free Pascal wiki, page "Bit manipulation/fr", as it stood on 2020-02-10 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history