Mega Code Archive

 
Categories / Delphi / Algorithm Math
 

A little Bit

Title: A little Bit Question: Sometimes you need a little bitmanipulation, but you are worried about all those AND, OR, XOR, SHL and SHR? So why don''t you give a simple but smart set a chance? Answer: First of all, we give the bits names for better handling: type Bits = (Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7, Bit8, Bit9, Bit10, Bit11, Bit12, Bit13, Bit14, Bit15, Bit16, Bit17, Bit18, Bit19, Bit20, Bit21, Bit22, Bit23, Bit24, Bit25, Bit26, Bit27, Bit28, Bit29, Bit30, Bit31, Bit32, Bit33, Bit34, Bit35, Bit36, Bit37, Bit38, Bit39, Bit40, Bit41, Bit42, Bit43, Bit44, Bit45, Bit46, Bit47, Bit48, Bit49, Bit50, Bit51, Bit52, Bit53, Bit54, Bit55, Bit56, Bit57, Bit58, Bit59, Bit60, Bit61, Bit62, Bit63); Then we define the sets: type TByteBits = set of Bit0..Bit7; TWordBits = set of Bit0..Bit15; TLongBits = set of Bit0..Bit31; TInt64Bits = set of Bit0..Bit63; // or set of Bits; Thats nearly all. To set, clear or test a bit, we just use the usual set operators: Set: Include (mybitset, Bit24); Clear: Exclude (mybitset, Bit15); Test: if Bit5 in mybitset then ... Even you can do bitwise manipulation: AND: mybitset:= [Bit7, Bit8] * [Bit5, Bit6]; OR: mybitset:= [Bit7, Bit5] + [Bit5, Bit6]; To transfer numeric values to the Bitsets you can use this functions function ValToByteBits (CONST v8: Byte): TByteBits; // convert a Byte to a Bitset var b: TByteBits absolute v8; begin Result:= b; end; function ValToWordBits (CONST v16: Word): TWordBits; // convert a Word to a Bitset var b: TWordBits absolute v16; begin Result:= b; end; function ValToLongBits (CONST v32: Integer): TLongBits; // convert a Longword to a Bitset var b: TLongBits absolute v32; begin Result:= b; end; function ValToInt64Bits (CONST v64: Int64): TInt64Bits; // convert a Int64 to a Bitset var b: TInt64Bits absolute i64; begin Result:= b; end; These functions turn the set back tu an numeric value: function BitsToByte (CONST v8: TByteBits): Byte; // convert a Bitset to a Byte var b: Byte absolute v8; begin Result:= b; end; function BitsToWord (CONST v16: TWordBits): Word; // convert a Bitset to a Word var b: Word absolute v16; begin Result:= b; end; function BitsToInteger (CONST v32: TLongBits): Integer; // convert a Bitset to a Integer var b: Integer absolute v32; begin Result:= b; end; function BitsToInt64 (CONST v64: TInt64Bits): Int64; // convert a Bitset to a Int64 var b: Byte absolute v64; begin Result:= b; end; As you see, we use the "absolute" directive to advice the compiler to put the local variable "on top" of the function parameter. With this technique the compiler produces a minimum of code and we get high performance. At last I will show you a function, that will count the number of Bits (or Elements) in a given variable. In this function we use a special pascal feature, the "anonymous parameter". The parameter "setvar" is declared without any type. In fact, when we call the function we can put any variable on this place - not only a set for example, but we need to know the concrete size in bytes of the parameter to avoid reading outside the variable. To inner restrictions of the function, the size of the variable is limited to 256 Bit (the maximum size for a set). If you need more, make the TBitArray bigger. function CountBits (CONST setvar; size: Integer): Integer; // First we declare an array of Bitsets: type TBitArray = array [0..31] of TByteBits; // We set it on top of setvar var bits: TBitArray absolute setvar; i, c: Integer; // counting cariables b: Bits; begin c:= 0; // start value for number of bits // count the number of bytes for i:= 0 to size - 1 do begin // for each byte count the number of bits for b:= Bit0 to Bit7 do begin if b in bits[i] then Inc (c); end; end; Result:= c; end;