Algorithm Math Delphi

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;