Bitwise Operators
Wow bitwise operators, these were very difficult for me to understand. It seemed many other programmers
understood them way before I did. So, I hope you find it easy - but if not don't worry because neither did I!
Bitwise operators allow you to do logical operations on a set of bits. What are bits? Remember that a computer
stores all your variables in memory locations. Your variables are represented as bits of data. (zeros and ones).
If you declare a char:
char letter = 'A';
It is actually storing the letter 'A' as bits in a memory address. So how do zeros and ones become an 'A'? Like this:
A char is 1 byte of data. There are 8 bits in 1 byte, so you could also say that a char is 8 bits of data. An uppercase A is
number 65 in the ascii table. Since we have declared it as a 'char' the compiler knows to place 65 in that memory address.
So now we have converted the letter to a number. But how does 65 become zeros and ones? Read on:
A computer stores a 0 or 1 for each bit (this is known as base 2, as humans we use base 10). So if we have 8 bits, you can invision it like this: 0000 0000
Bits are referred to as on or off, if they are on the bit is 1, off is 0. To translate a series of bits into base 10 you simply start at the
Least Significant Bit (the bit on the right, known as LSB) and double the value for each next bit. Like this:
0000 0001 is 1 in base 10
0000 0010 is 2 in base 10
0000 0100 is 4 in base 10
0000 1000 is 8 in base 10
0001 0000 is 16 in base 10
0010 0000 is 32 in base 10
0100 0000 is 64 in base 10
1000 0000 is 128 in base 10
If more than 1 bit is active, you add the final results together:
0000 0011 is 1 in base 10 + 2 in base 10, so the final result is 3
0000 0110 is 6 in base 10
0000 1001 is 9 in base 10
So the computer can store the number 65 (which translates to 'A' in our ascii table) as:
0100 0001 because we have 64 + 1
The computer can use as many bits as you want, and the variable declaration tells it how many bits to use. As I said
earlier, a char is 8 bits, if all the bits of the char were on it would be
1111 1111 which is 255 in base 10. This means that the largest number or letter value a char can hold is 255
So Bitwise Operators allow you to perform operations on these individual bits, for instance to see if a certain bit is on.
But there is a problem, you can't type straight binary numbers into the compiler and base 10 numbers don't map very well to
their binary representation. Because of this, many programmers use hexidecimal (which is base 16). You can enter a hexidecimal
number into the compiler as long as you put a '0x' in front of it. Each hexidecimal number
can be 0 through 16 - represented as a single character 0x0 through 0xf. 0x0 through 0x9 are the same as 0 through 9 in base 10.
0xa through 0xf are 10 through 15 in base 10.
So why is hexidecimal easier? Because it's easier to visualize as its binary counterpart.
0x0f is 16 which is the same as the 5th least significant bit (LSB) being on (0001 0000).
0xff is 255 which is the same as all 8 least significant bits (LSB) being on (1111 1111).
I don't expect you to take this all in at once. But you need to be aware of hexidecimal numbers
because you will see (and eventually use) it often. One fun trick is to load up Windows calculator
and change it to scientific mode. Then type in a number and press the binary and hexidecimal radio button
to see the different ways you can represent your number!
So now the hard part :)
As we dive into further programming. You'll come across instances where variables need to hold
more than one item of information. For instance, lets say a single variable held information about a file.
It might hold if the file is read only, if the file is marked for archive and if the file is locked.
Rather than hold 3 separate variables, you can store this on or off type data in different bits.
We'll say the file locked bit is the first bit (the LSB) bit, 0001 if the file is locked. We'll use the second bit
(on or off) if the file is marked for archive 0010, means the file is marked for archive. We'll use the third
bit to say if a file is read only, 0100 means a file is read only. We only need 4 bits total to hold our information
so we'll use a char, which is capable of 8 bits incase we need to expand.
char fileStatus = 0x0;
See, I used hexidecimal here (the same as if I had just used 0) and all the bits are off. If I wanted to say
the file is locked and read only I would want to put 0101. Since I can't put binary I'd put the hexidecimal equivilant:
char fileStatus = 0x05;
If you open your calculator and choose hex and put 5 in, then choose binary it converts it to 101 which is the same as 0101.
So lets say you have someone else give you the fileStatus variable and you want to see if it's read only, you can't just do ==
0100 because it might also be locked so the variable would be 0101. so your == would fail. You need to see if just
the read only bit is set and not care about the other bits, to do that you use the AND operator.
if ( fileStatus & 0x08 )
Remember we use hexidecimal 0x8 which is the binary 0100. This is saying, if the 3rd bit is on, which translates to
if the read only bit is on. What AND does is returns true if the same bit on the left of the operator and the right are on. Since
the bit on the left in fileStatus was set to read only and the bit on the right 0x08 is also read only, it returns true.
The OR operator (the pipe, |), allows you to turn a bit on or off. Lets say you have the fileStatus
variable and you want to turn the read only bit on, you would do:
fileStatus = fileStatus | 0x08;
This says use all the bits in fileStatus and also the read only bit. Basically OR means combine all the on bits on the left
of the operator and all the on bits on the right.
This tutorial is by far enough to make your head spin. I don't expect you to understand all of it, but I want to make you
aware of these bitwise operators and hexidecimal representations because you will come across them frequently in programming.
I promise that if you stick with programming, one day it will just click and make sense!
|