in reply to Re: bitwise operators
in thread bitwise operators
But to keep it simple, I always remember
"AND and OR, multiply and plus."
That's because with single-digit binary numbers, AND gives you the same result as multiplication and the same goes for OR and addition. (A truth table, which shows the grid of all possible pairs and the result you get for a given operation, is helpful.)
Understanding binary is good in Perl when you want to check the return value of a system function, since it may look like 128 for example but you know it is just the 8th bit that is set to 1. You can shift that bit left or right to simulate multiplication or division by two.
Binary logic is also the fundamental idea behind the operators "and", "or", "|", "||", "&", and "&&". If you ever use all capitals constants for system control you are probably using binary without realizing it. You also need to know what you are doing here when you tie a database or use other routines that let you hand them a number of boolean (single bit) flags.
Also if you are doing Perl in windows or talking to a C program, you may very well need to set "flags" or use a "bit mask". For example, say you have a window drawing function and it treats each bit of an argument as a display option. Perhaps the second bit means "the window has beveled edges" and the fourth bit means "vertical scrollbar should be displayed". Then you would want to set both bits to specify both options, in other words take a string of 8 zeroes and set the second and fourth bits to ones (usually we count right to left so the first bit is on the right). In base two you get 00001010 (in base two, or binary) or 2^1 + 2^3 = 2+8 = 10 (in base 10).
Now If you got the current setting and it was 8 (scrollbar displayed) and you wanted to add bevelled edges, you could add (binary OR) that value (8, or in binary 00001000) with your bit mask (10, or in binary 00001010). Since OR is like addition, it makes sense that every digit set to one in your mask will become set. Likewise, if you had used AND, every bit set to zero in your mask would be cleared because anything AND 0 is like multiplying. by zero.
Usually these display options are given all capitals names like V_SCROLLBAR and BEVELED_EDGE. Then if you have a function DrawWindow that takes three bytes (x, y, and type) as arguments, you can draw a window at coordinates x and y with something like DrawWindow(x,y,V_SCROLLBAR|BEVELED_EDGE).
So the more bits you have, the more options you can set. This is really the front end for the C or C++ code in which the function was originally written, and the byte size of each argument is predefined. This means that you can only specify up to eight window options at once if type is only one byte long. So you may see a function called something like DrawWindowEx which might be a function that might allows many more settings because it had a 32 bit (4 byte) argument.
Another example is this snippet from DB_File.pm:
sub LOCK_SH { 1 }
sub LOCK_EX { 2 }
sub LOCK_NB { 4 }
sub LOCK_UN { 8 }
...
unless (flock (DB_FH, LOCK_EX | LOCK_NB)) { .... }
That means a file lock on the file handle DB_FH is being requested and that the lock should be both exclusive and nonblocking. Unless flock returns a number greater than 0, the .... code is executed.
So now you can read this too:
$db = tie(%db, 'DB_File', '/tmp/foo.db', O_CREAT|O_RDWR, 0644)
|| die "dbcreat /tmp/foo.db $!";
You see someone (Paul Marquess, writer of that module) was trying to tie a hash variable (db) to a file (foo.db) using the DB_File module and opening the database file with file creation and Read/Write permission.
In the last line of code above, you see bitwise OR (single pipemark) being used to add two flags, and you also see logical OR (double pipe, synonymous with "or") which will cause the "die" code to be executed if Perl decides it needs to look at it to evaluate the entire line. It is neat that "die" is not looked at if what comes before the double pipe is true, since in bitwise addition you already know the answer if you can tell the first value of your pair of binary digits is true (i.e. set to one). So binary logic is pretty important in Perl!
By the way if you are curious what kind of constants are out there, you can check out Fcntl.pm, or (in unix) try "man fcntl" to see what the values are on your system. A Windows programmer's guide will also be full to the brim with these all caps flags.
|
|---|