Sign in Join
Wiki copytemporary

Bit manipulation/de: what changed

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

Title: Bit manipulation/de

OldNewLine
1+\
2+\
3+
4+# Maskierte Operationen
5+
6+Dieses Beispiel ist ein einfacher Ansatz zur Bit-Manipulation. Das Beispiel bietet den Vorteil, dass Operationen, mit Bit-Gruppen, auf einmal durchgeführt werden.\
7+
8+``` pascal
9+procedure ClearBit(var Value: QWord; Index: Byte);
10+begin
11+ Value := Value and ((1 shl Index) xor High(QWord)));
12+end;
13+
14+procedure SetBit(var Value: QWord; Index: Byte);
15+begin
16+ Value := Value or (QWord(State) shl Index);
17+end;
18+
19+procedure PutBit(var Value: QWord; Index: Byte; State: Boolean);
20+begin
21+ Value := (Value and ((1 shl Index) xor High(QWord))) or (QWord(State) shl Index);
22+end;
23+
24+function GetBit(Value: QWord; Index: Byte): Boolean;
25+begin
26+ Result := ((Value shr Index) and 1) = 1;
27+end;
28+```
29+
30+\
31+=Bitpacked record= Die Verwendung von bitpacked records, wird durch die lokale Compilerdirektive {\$BITPACKING ON} ermöglicht.\
32+\
33+Der Free Pascal Compiler bietet die Möglichkeit einzelne Bits im Speicher anzusprechen. Mit dem Beispiel kann sowohl das ganze Byte als auch das einzelne Bit in diesem Byte angeprochen werden.\
34+Dies kann man mit einem Record oder einem Array lösen.\
35+\
36+
37+``` pascal
38+ ...
39+
40+ // Compilerdirektive
41+ {$BITPACKING ON}
42+
43+ ...
44+
45+type
46+ TByteBits = bitpacked record
47+ Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7: Boolean;
48+ end;
49+
50+ TByteEx = packed record
51+ case Integer of
52+ 0: (ByteAccess: Byte);
53+ 1: (BitAccess: TByteBits);
54+ 3: (BitArray: bitpacked array[0..7] of Boolean);
55+ end;
56+
57+ ...
58+
59+```
60+
61+\
62+Beispiel für die Verwendung von TByteBits und TByteEx:
63+
64+``` pascal
65+ // Wertzuweisung als Byte
66+ ByteEx.ByteAccess := 4;
67+
68+ // Ändert den Wert von Bit7 und damit den Wert
69+ // der über ByteEx.ByteAccess wieder ausgelesen wird
70+ // in diesem Beispiel beträgt der Wert in
71+ // ByteEx.ByteAccess 132
72+ ByteEx.BitAccess.Bit7 := True;
73+
74+ // Über die Array
75+ ByteEx.BitArray[7] := True;
76+```
77+
78+\
79+
80+# Set
81+
82+\
83+In Sets kann man die Bits eintragen, die für die Bitmanipulation in frage kommen.\
84+
85+``` pascal
86+
87+ ...
88+
89+ // Compilerdirektiven
90+ {$packset 1}
91+ {$packenum 1}
92+
93+ ...
94+
95+ type
96+ TSetByteBits = set of (Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7);
97+
98+ ...
99+
100+ var
101+ SetByteBits: TSetByteBits;
102+ ...
103+
104+ begin
105+
106+ ...
107+
108+ // legt fest, welche Elemente im Set gespeichert werden
109+ SetByteBits := [Bit0 .. Bit7];
110+
111+ // Startet eine Bitmanipulation, wenn Bit3 im Set gefunden wird
112+ if Bit3 in SetByteBits then
113+ begin
114+ ...
115+ end;
116+
117+ ...
118+
119+ end;
120+
121+ ...
122+
123+```
124+
125+\
126+
127+# TBits
128+
129+\
130+Diese Klasse ist Teil der Klasse Unit aus der Free Pascal RTL Bibliothek. Die Klasse bietet einige Methoden zur Bit-Manipulation.
131+
132+``` pascal
133+ TBits = class(TObject)
134+ public
135+ constructor Create(TheSize : longint = 0); virtual;
136+ destructor Destroy; override;
137+ function GetFSize : longint;
138+ procedure SetOn(Bit : longint);
139+ procedure Clear(Bit : longint);
140+ procedure Clearall;
141+ procedure AndBits(BitSet : TBits);
142+ procedure OrBits(BitSet : TBits);
143+ procedure XorBits(BitSet : TBits);
144+ procedure NotBits(BitSet : TBits);
145+ function Get(Bit : longint) : boolean;
146+ procedure Grow(NBit : longint);
147+ function Equals(Obj : TObject): Boolean; override; overload;
148+ function Equals(BitSet : TBits) : Boolean; overload;
149+ procedure SetIndex(Index : longint);
150+ function FindFirstBit(State : boolean) : longint;
151+ function FindNextBit : longint;
152+ function FindPrevBit : longint;
153+
154+ // Funktionen und Eigenschaften zu entsprechen TBits class
155+ function OpenBit: longint;
156+ property Bits[Bit: longint]: Boolean read get write SetBit; default;
157+ property Size: longint read FBSize write setSize;
158+ end;
159+```
160+
161+\
162+Beispiel für eine Verwendung:
163+
164+``` pascal
165+ ...
166+
167+ var
168+ Bits: TBits;
169+ bytI: Byte;
170+
171+ begin
172+
173+ ...
174+
175+ // Erstellt das Objekt
176+ Bits := TBits.Create;
177+
178+ // Legt die Grösse fest
179+ Bits.Size := 5;
180+
181+ // legt für einige Bits den Wert fest
182+ Bits[0] := true;
183+ Bits[1] := true;
184+ Bits[4] := true;
185+
186+ // Ausagbe der Werte
187+ for bytI := 0 to Bits.Size-1 do
188+ if Bits[bytI] = true
189+ then ShowMessage(inttostr(bytI) + ' ' + BoolToStr(Bits[bytI]))
190+ else ShowMessage(inttostr(bytI) + ' ' + BoolToStr(Bits[bytI]));
191+
192+ // gibt den Speicher des Objektes wieder frei
193+ Bits.Free;
194+
195+ ...
196+
197+ end;
198+
199+ ...
200+```
201+
202+\
203+=Record Eigenschaften und Wertindex=\
204+Another interesting implementation of bit aligned structure can be used with capabilities of advanced records (FPC 2.6.0+). For all properties you have to use setter and getter which can handle general bit manipulations and set index which is passed to these methods. For more information refer to [Indexed properties](http://www.freepascal.org/docs-html/ref/refsu31.html). Because index is only one, it has to be divided to two parameters to describe location and size on bit value. In case of the following example, the offset can be 0..255 and size of value 0..255 bits. Another problem is that you have to ensure that defined structure components will not overlay.
205+
206+``` pascal
207+{$mode delphi}
208+
209+ TSomeBitStructure = record
210+ private
211+ RawData: Word;
212+ function GetBits(const AIndex: Integer): Integer; inline;
213+ procedure SetBits(const AIndex: Integer; const AValue: Integer); inline;
214+ public
215+ // High byte of index offset, low byte of index is bit count
216+ property OneBit: Integer index $0001 read GetBits write SetBits;
217+ property TwoBits: Integer index $0102 read GetBits write SetBits;
218+ property FourBits: Integer index $0304 read GetBits write SetBits;
219+ property EightBits: Integer index $0708 read GetBits write SetBits;
220+ end;
221+
222+{$OPTIMIZATION ON}
223+{$OVERFLOWCHECKS OFF}
224+function TSomeBitStructure.GetBits(const AIndex: Integer): Integer;
225+var
226+ Offset: Integer;
227+ BitCount: Integer;
228+ Mask: Integer;
229+begin
230+ BitCount := AIndex and $FF;
231+ Offset := AIndex shr 8;
232+ Mask := ((1 shl BitCount) - 1);
233+ Result := (RawData shr Offset) and Mask;
234+end;
235+
236+procedure TSomeBitStructure.SetBits(const AIndex: Integer; const AValue: Integer);
237+var
238+ Offset: Integer;
239+ BitCount: Integer;
240+ Mask: Integer;
241+begin
242+ BitCount := AIndex and $FF;
243+ Offset := AIndex shr 8;
244+ Mask := ((1 shl BitCount) - 1);
245+ Assert(aValue <= Mask);
246+ RawData := (RawData and (not (Mask shl Offset))) or (AValue shl Offset);
247+end;
248+```
249+
250+---
251+*From the Free Pascal wiki, page "Bit manipulation/de", 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