PDA

View Full Version : In-depth Bitwise Operators.



R0b0t1
07-30-2008, 06:10 AM
Return the value of a select bit/Finding single bit index.



Returning the value of a bit at a known location is simple:


Result := Boolean(Val and $1);


Here, $1 (this really does not need to be in Hex), is 0000-0001. This is one byte. Now, for example, if the value we were comparing/checking was 1001-1100, then:



1001-1100 AND
0000-0001
0000-0000


Now what this means is that once it passes through the "Boolean()" function, it is now any type, here it will be a boolean value. Since everything is zero, it is false (other way for true). Therefore, we know that the first bit starting from the right side. We can check more places, starting from the right, like this:


Start at place 1 (or 0). This is the farthest to the right.
Now, at bit 1, the value 1 will set only this bit. With this as our constand, we can either:

To move to the left, multiply by 2. If we start at one, then 1 x 2 = 2. So (Val and 2) is (where Val is 1001-1010):



1001-1010 AND
0000-0010
0000-0010


would be true (once put inside the Boolean function), because it is not zero. You can carry this on, so 2 x 2 = 4; it would be 0000-0100 and would check the third bit from the right.
To move to the left, divide by 2 (you may have guessed). If we start at bit 8, (1000-0000 is decimal 128), 128 / 2 = 64 / 2 = 32 (32 is 0010-0000). To check the sixth bit then, we can do (where Val is 1110-0101):



1110-0101 AND
0010-0000
0010-0000






would again be true, as it is a value other than zero. We will use this multiplication/division later.

Here is a function to check the bits of a byte (returns true if bit is set, note 1 is bit 1, you can make it start at zero. P is the place to check):


function GetBt(V, P: Byte): Boolean;
begin
Dec(P);
Result := Boolean(V and (1 shl P));
end;






Setting a single bit.



Setting a bit is a little harder. But can also be easy with the multiplication principles. You set a bits with 'or' and 'and', also 'not'.

If Val is 1011-0110, then:


Val := Val or 1;




1011-0110 OR
0000-0001
1011-0111


This will set the first bit to 1, and if it was already 1, it will have no effect (We set the variable as its own result because you obviously want the change in that variable). You can also make them zero by using and and not.

If val is 0010-1111, then, to set bit 4:


Val := Val and not 4;




0010-1111 AND
1111-1011 = not 0000-0100
0010-1011


Do you see how that one bit is now a zero? Now, we will make a function (Here, V is the value, P is the place to set, and T is the new value, 1 or 0; again we use 1..8).


procedure SetBt(var V: Byte; P, T: Byte);
begin
Dec(P);
if T > 0 then
Result := V or (1 shl P)
else
Result := V and not (1 shl P);
end;






Getting the bytes out of a larger value.



There is only one way I know of, which includes shifting the bits and then anding them with $FF. In SCAR, this can be done much easier with just shifting (Heres why: If you try to assign a value larger than an byte to a byte, you get an overflow error, a "range check" in delphi/SCAR. It just cuts off the unneeded bytes.)

We go right to the code this time (V is the value, and P is how many bytes to shift it over):


function GetDown(V: Integer; P: Byte): Byte; //pun intended. GetLow would be a better name.
begin
P := P * 8;
V := V shr P;
Result := V;
end;


You might be wondering what all of this shr and shl stuff is. It stands for (may have guessed it) SHift Right and SHift Left. How they work is by moving the whole number, binary style, over to the left/right. Historically, they would drop off the bits that went over the side, padding the rest with zeros, but it appears Delphi wraps them arround, which is convienient, as Delphi does not have the ror and rol routines, which are like shl and shr, but put the stuff that goes over back on the other side (1000 ror 5 = 1000).




If there are any problems with the examples, please post on the thread.

bullzeye95
07-30-2008, 07:44 AM
Nice tutorial. You are just wrong about Delphi's shr and shl being ror and rol. They are just shl and shr.

R0b0t1
07-30-2008, 08:35 AM
Really? I pulled it off with my compiler and instead of being 0, it was a really high number. Which means it did not throw away the zeros.

CallOfVideos
09-02-2008, 06:32 PM
Great tut man. i still dont get it 100% though