Mega Code Archive

 
Categories / Delphi / Examples
 

32 Bit Manipulation and Conversion Class

Title: 32 Bit Manipulation and Conversion Class Question: This class allows conversion and bit manipulation of a 32 bit integer. Values may be set and retrieved as INT,HEX or BINARY. Individual bits may be SET,TOGGLED,ROTATED WITH CARRY and CLEARED as well as Checking for ON-OFF status. Most methods allow for a SINGLE bit number parameter and a MULTI bit number parameter as an "array of byte". Bit numbers are 0..31 from right to left. ie. 31,30,29 ..... 4,3,2,1,0 Properties AsInteger - Get or Set value as an integer AsHex - Get or Set value as a Hex String AsBinary - Get or Set value as a Binary String Methods (Functions) BitSet() - Return if bit number is set. BitsSet() - Return if a an array of bit numbers are all set Methods (Procedures) SetBit() - Sets a single bit number to 1 SetBits() - Sets an array of bit numbers to 1 ClrBit() - Clears a single bit number to 0 ClrBits() - Clears an array of bit numbers to 0 ToggleBit() - Toggle a single bit number 0=1 1=0 ToggleBits() - Toggles an array of bit numbers to 0=1 1=0 RotateLeft - Shifts the value left by 1 with lost bit in bit 0 RotateRight - Shits the value right by 1 with lost bit in bit 31 Whilst the class can be used as conversion class from INT to HEX to BINARY, it's main purpose is the manipulation of bits in a 32 bit value. Examples var oBit32 : TBit32; .... oBit32 := TBit32.Create; oBit32.AsInteger := 34212; ShowMessage(oBit32,AsBinary); // '00000000000000000100001011010010' ShowMessage(oBit32.AsHex) // '000042D2 ' oBit32.AsBinary := '110110'; // and so forth oBit32.SetBit(10); oBit32.RotateLeft; if oBit32.BitsSet([2,4,8]) then .... oBit32.Free; Answer: unit MahBit32; interface // ======================================================================== // 32 Bit Manipulation/Conversion Class // Mike Heydon Nov 2004 // // This class allows conversion and bit manipulation of a 32 bit integer. // Values may be set and retrieved as INT,HEX or BINARY. // Individual bits may be SET,TOGGLED,ROTATED and CLEARED, // Checked for ON-OFF status. // Bit numbers are 0..31 from right to left. // ie. 31,30,29 ..... 4,3,2,1,0 // // Properties // ---------- // AsInteger - Get or Set value as an integer // AsHex - Get or Set value as a Hex String // AsBinary - Get or Set value as a Binary String // // Methods (Functions) // -------------------- // BitSet() - Return if bit number is set. // BitsSet() - Return if a an array of bit numbers are all set // // Methods (Procedures) // -------------------- // SetBit() - Sets a single bit number to 1 // SetBits() - Sets an array of bit numbers to 1 // ClrBit() - Clears a single bit number to 0 // ClrBits() - Clears an array of bit numbers to 0 // ToggleBit() - Toggle a single bit number 0=1 1=0 // ToggleBits() - Toggles an array of bit numbers to 0=1 1=0 // RotateLeft - Shifts the value left by 1 with lost bit in bit 0 // RotateRight - Shits the value right by 1 with lost bit in bit 31 // // ======================================================================== uses SysUtils; type {TBIT32 CLASS} TBit32 = class(TObject) private FValue : integer; function GetFAsHex : string; procedure SetFAsHex(const AValue : string); function GetFAsBinary : string; procedure SetFAsBinary(const AValue : string); protected // Internal Methods procedure _CheckBitNumber(ABitNumber : byte); function _CalcMask(ABitNumArray : array of byte) : longword; public // Methods (Functions) function BitSet(ABitNumber : byte) : boolean; function BitsSet(ABitNumArray : array of byte) : boolean; // Methods (Procedures) procedure SetBit(ABitNumber : byte); procedure SetBits(ABitNumArray : array of byte); procedure ClrBit(ABitNumber : byte); procedure ClrBits(ABitNumArray : array of byte); procedure ToggleBit(ABitNumber : byte); procedure ToggleBits(ABitNumArray : array of byte); procedure RotateRight; procedure RotateLeft; // Properties property AsInteger : integer read FValue write FValue; property AsHex : string read GetFAsHex write SetFAsHex; property AsBinary : string read GetFAsBinary write SetFAsBinary; end; // ------------------------------------------------------------------------ implementation const C_BITVALARR : array [0..31] of longword = ($00000001,$00000002,$00000004,$00000008,$00000010, $00000020,$00000040,$00000080,$00000100,$00000200, $00000400,$00000800,$00001000,$00002000,$00004000, $00008000,$00010000,$00020000,$00040000,$00080000, $00100000,$00200000,$00400000,$00800000,$01000000, $02000000,$04000000,$08000000,$10000000,$20000000, $40000000,$80000000); // ============================================= // Internal routine to validate bit number 0..31 // Will raise EConvertError Exception if fails // ============================================= procedure TBit32._CheckBitNumber(ABitNumber : byte); begin if not (ABitNumber in [0..31]) then raise EConvertError.Create(IntToStr(ABitNumber) + ' is not a valid bit number (0..31)'); end; // ============================================================ // Internal routine to return a binaray mask from an array of // bit numbers // ============================================================ function TBit32._CalcMask(ABitNumArray : array of byte) : longword; var i : integer; iResult : longword; begin iResult := 0; for i := low(ABitNumArray) to high(ABitNumArray) do begin _CheckBitNumber(ABitNumArray[i]); iResult := iResult or C_BITVALARR[ABitNumArray[i]]; end; Result := iResult; end; // ============================================== // Get/Set Property Methods // ============================================== function TBit32.GetFAsHex : string; begin Result := IntToHex(FValue,8); end; procedure TBit32.SetFAsHex(const AValue : string); begin try FValue := StrToInt('$' + AValue); except raise EConvertError.Create(QuotedStr(AValue) + ' is not a valid hex value'); end; end; function TBit32.GetFAsBinary : string; var sResult : string; iValue : integer; begin sResult := ''; iValue := FValue; while iValue 0 do begin sResult := char(48 + (iValue and 1)) + sResult; iValue := iValue shr 1; end; Result := StringOfChar('0',32 - length(sResult)) + sResult; end; procedure TBit32.SetFAsBinary(const AValue : string); var i : integer; sValue : string; begin // Validate is a valid binary string for i := 1 to length(AValue) do begin if not (AValue[i] in ['0','1']) then begin raise EConvertError.Create(QuotedStr(AValue) + ' is not a valid binary value'); break end; end; // Convert to binary string sValue := StringOfChar('0',32 - length(AValue)) + AValue; FValue := 0; for i := 1 to length(sValue) do FValue := (FValue shl 1) + (byte(sValue[i]) and 1) ; end; // ============================================ // Return true if bit number of Value is set // ============================================ function TBit32.BitSet(ABitNumber : byte) : boolean; begin _CheckBitNumber(ABitNumber); Result := FValue and C_BITVALARR[ABitNumber] = C_BITVALARR[ABitNumber]; end; // ============================================ // Return true if bit numbers of Value are set // Bit numbers are passed in array parameter // eg. if MyBit32.BitsSet([3,7,12]) then ... // ============================================ function TBit32.BitsSet(ABitNumArray : array of byte) : boolean; var iMask : longword; begin iMask := _CalcMask(ABitNumArray); Result := FValue and iMask = iMask; end; // =============================================== // Set a bit (bit = 1) by bit number 0..31 // =============================================== procedure TBit32.SetBit(ABitNumber : byte); begin _CheckBitNumber(ABitNumber); FValue := longword(FValue) or C_BITVALARR[ABitNumber]; end; // =============================================== // Set bits (bit = 1) by bit number array // eg. MyBit32.SetBits([12,13,20]); // =============================================== procedure TBit32.SetBits(ABitNumArray : array of byte); var iMask : longword; begin iMask := _CalcMask(ABitNumArray); FValue := longword(FValue) or iMask; end; // =============================================== // Clear a bit (bit = 0) by bit number 0..31 // =============================================== procedure TBit32.ClrBit(ABitNumber : byte); begin _CheckBitNumber(ABitNumber); FValue := (longword(FValue) or C_BITVALARR[ABitNumber]) xor C_BITVALARR[ABitNumber]; end; // =============================================== // Clear bits (bit = 0) by bit number array // eg. MyBit32.ClrBits([12,13,20]); // =============================================== procedure TBit32.ClrBits(ABitNumArray : array of byte); var iMask : longword; begin iMask := _CalcMask(ABitNumArray); FValue := (longword(FValue) or iMask) xor iMask; end; // =============================================== // Toggle a bit (0=1 1=0) by bit number 0..31 // =============================================== procedure TBit32.ToggleBit(ABitNumber : byte); begin _CheckBitNumber(ABitNumber); FValue := longword(FValue) xor C_BITVALARR[ABitNumber]; end; // =============================================== // Toggle bits (0=1 1=0) by bit number array // eg. MyBit32.ToggleBits([12,13,20]); // =============================================== procedure TBit32.ToggleBits(ABitNumArray : array of byte); var iMask : longword; begin iMask := _CalcMask(ABitNumArray); FValue := longword(FValue) xor iMask; end; // ==================================================== // Rotate the value left by 1 // The lost bit in bit 31 is restored in bit 0 // ==================================================== procedure TBit32.RotateLeft; var bBit31Set : boolean; begin bBit31Set := FValue and $80000000 = $80000000; FValue := FValue shl 1; if bBit31Set then FValue := FValue or 1; end; // ==================================================== // Rotate the value right by 1 // The lost bit in bit 0 is restored in bit 31 // ==================================================== procedure TBit32.RotateRight; var bBit00Set : boolean; begin bBit00Set := FValue and 1 = 1; FValue := FValue shr 1; if bBit00Set then FValue := longword(FValue) or $80000000;; end; end.