Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit Manipulation Delphi in XML - Bitwise

I am a student in high school and I am currently learning in Delphi XE3. We are learning about BIT manipulation. We have an assignment and while I have read a lot on the subject and understand the entire process of storing information in Bits and SHL/SHR I am having difficulty understanding how to do this process in Delphi.

The assignment is as follows:

Decimal        Hexidecimal    Binary
1              0x0001         0000000000000001
2              0x0002         0000000000000010
4              0x0004         0000000000000100

Passing an integer value in an XML file to identify the options set. For example. If I wanted to send option 1 and option 2, I would add 1+2=3. I would send 3 as the number to specify that options 1 and 2 are true.

On the client the binary value would be 0000000000000011 = 3

From what I have read I need to use a mask but I do not understand how to do this. How would do I use masks in Delphi ot obtain the individual values which would be True or False.

I tried doing this in a regular Integer variable but it always gets treated as an Integer and the result is very strange. If I convert the integer to a binary string representation and I iterate thru the characters the result is correct but I am assuming that I should not be doing this with strings. Any help or an example would be greatly appreciated. Thank you.

like image 869
LHearn Avatar asked Jan 23 '13 18:01

LHearn


2 Answers

You usually check if a particular bit is set in a Integer variable using the and binary operator, and you set individual bits using the or operator, like this:

const
  OPTION_X = $01;
  OPTION_Y = $02;
  OPTION_Z = $04;

var
  Options: Byte;
begin
  Options := OPTION_X or OPTION_Y;  //actually 3, like in your example
  //check if option_X is set
  if (Options and OPTION_X) = OPTION_X then
    ShowMessage('Option X is set');  //this message is shown, because the bit is set
  //check if option_Z is set
  if (Options and OPTION_Z) = OPTION_Z then
    ShowMessage('Option Z is set');  //this message is NOT shown
end;

The different OPTION_ constants, are actually masks, in the sense they are used to mask bits to zero (to check if a particular bit is set) or to mask bits to 1 (to set a particular bit).

Consider this fragment:

begin
  ..

  if cbOptionX.Checked then
    Options := Options or OPTION_X;
  ..

the or will mask the first bit to 1. If we start with a Options value (in binary) of 01010000, the resulting Options would be 01010001

    01010000   
 OR 00000001  //OPTION_X 
  = 01010001   

the same value is used to mask all the other bits to 0 to check if a particular bit is set. The if condition, for example: (Options and OPTION_Z) = OPTION_Z, does this:

  • first it MASKS all the non-interesting bytes of the Option variable to 0. If we consider the last value of 01010001, the operation will result in clearing all the bits, but the first.

        01010001   
    AND 00000001   
      = 00000001   
    

considering a starting value of 01010000 it will return zero:

        01010000   
    AND 00000001   
      = 00000000   
  • next, it compares if that value is equal to the mask itself. If it is equal, the bit was set in the original Options variable, otherwise it was not set. If your mask contains only one bit, that's matter of taste, you can just check if the resulting value is, for example, different than 0, but if your mask contains multiple bits and you want to check if all the bits was set, you have to check for equality.
like image 95
jachguate Avatar answered Sep 28 '22 11:09

jachguate


Delphi has a predefined type TIntegerSet which allows to use set operators. Assuming that options is an Integer, you can check if any bit (0-based) is set like this:

option1 := 0 in TIntegerSet(options); { Bit 0 is set? }
option3 := 2 in TIntegerSet(options); { Bit 2 is set? }

Changing the options is done via Include or Exclude:

Include(TIntegerSet(options), 0); { set bit 0 }
Exclude(TIntegerSet(options), 2); { reset bit 2 }

Of course you can use any other set operator that may be helpful.

like image 30
Uwe Raabe Avatar answered Sep 28 '22 10:09

Uwe Raabe