In this article, we'll finish learning about bits. We'll take a look at a few more operators and an important Perl function for working with bits. Finally, we'll implement the algorithm we looked at.
You may want to read the previous article if you haven't (or review it if you have) before you dive into this one.
The bitwise XOR and NOT operators
Maybe you recall that, from the last article, I said that the bitwise OR operator would set a resulting bit to 1 if one or both of the corresponding bits in the operands were 1. The key thing to notice here are that if both of the bits are 1, then the result is 1. The OR operator may be more appropriately termed an inclusive OR.
However, there is another operator worth mentioning, the exclusive OR, more commonly known as XOR. The bitwise XOR operator is represented by a carat symbol (^). The bitwise XOR operator will set a resulting bit to 1 if and only if one of the operands features a 1 as the corresponding bit.
For example, say that we have these two operands:
If we apply the bitwise XOR, then we get this result:
However, say we have these two operands:
If we apply the bitwise XOR to these operands, we get this result:
That's because, for the first and third bits, both operands feature a 1. The bitwise XOR operator requires that only one of the operands have a 1.
Remember how the bitwise AND operator can be used with a bit mask to check the value of a particular bit or set of bits? The bitwise XOR operator can also be used with a bit mask, but for a different purpose. Using the bitwise XOR operator and the appropriate bit mask, it is possible to toggle a specific bit or set of bits. For example, consider this number:
If we want to toggle the second bit, we could use the XOR operator with the appropriate bit mask (0100) to get this result:
Or, if we wanted to toggle the third bit, we could use the XOR operator with a different bit mask (0010):
Again, this is interesting and very useful behavior.
In order to see how this looks in Perl, let's recreate what we just did, but in Perl this time. These Perl lines apply the operations we just looked at, and then print the results:
my $bits = 0b1100;
printf "%bn", $bits ^ 0b0100;
printf "%bn", $bits ^ 0b0010;
Finally, there is the bitwise NOT operator (also called the bitwise negation operator, among other names), represented in Perl by a tilde symbol (~). If we oversimplify it, it's very easy to understand. The bitwise NOT operator, at an oversimplified level, “flips” each bit in an operand (it only takes one operand), turning each 1 into a 0 and each 0 into a 1.
In reality, however, the NOT operator is a bit more complex. The NOT operator returns a result based on your machine's integer size. So, on my machine, if I apply the operator on this operand:
Then I get this result:
Looking at the operand, you would expect the bitwise NOT operator to return 1000, and it does—but the result comes after a string of 1s. On my 64-bit machine, integers are 64 bits, so the four bits we want come after a string of sixty 1s.
Thankfully, it's easy to fix this using something you already know. In the above case, we want to extract the last four bits. Does this sort of thing sound familiar? We can use the bitwise AND operator and a bit mask to trim off all of the extra bits:
my $bits = ~0b1111;
$bits = $bits & 0b1111;
printf "%bn", $bits;
As you can see, it's not very difficult to get the behavior you want.
blog comments powered by Disqus