and the right one - how many positions to shift for.
For example, the following operations produce
| n = | 01100111 | = 103 |
| n << 2 = | 10011100 | = 156 |
| m = | 01001101 | = 77 |
| m >> 4 = | 00000100 | = 4 |
 |
Please note that the result of bitwise operations depend on how many bits are allocated to store the number. For example,
if we perform the same left shift operation on the same number 103 stored in 16-bit memory cell, then the
result would be 00000000 01100111 << 2 = 00000001 10011100 = 412.
|
Using combinations of these bitwise operators we can read/write each bit in a memory location.
Here you can find a simple HTML page that allows you to play with binary operators.
Accessing bits through a structure
Another way to access every bit of a memory location is to use the union construct of C/C++. This
construct allows us to access the same memory location in a different way. Sometimes it's convenient to think that
the union creates two (or more) different variables, but stores them in the very same memory cells.
For example, we can define a new type TInt by:
union TInt {
int int_value;
struct {
unsigned char byte_0;
unsigned char byte_1;
unsigned char byte_2;
unsigned char byte_3;
} bytes ;
};
Now, each variable data of the new type TInt can be accessed either as an integer value
by data.int_value or bytewise through the structure bytes located in
the same physical memory. For example, to access the lowest byte of the number we need to write
data.bytes.byte_0.
If we also use the additional opportunity given by the C++ language and specify the amount of bits each element of
a structure takes, we can provide bitwise access to the memory. To specify the bit capacity of a structure element, we
need to put a colon followed by the desired number of bits after the declaring a structure member. For example,
in the following structure element a takes only 3 bits, and element b only 5 bits:
struct Test {
unsigned int a:3;
unsigned int b:5;
}:
Using both of these constructions together we can define the following data type:
union ByteBitMap {
unsigned char byte_value;
struct {
unsigned int b0:1;
unsigned int b1:1;
unsigned int b2:1;
unsigned int b3:1;
unsigned int b4:1;
unsigned int b5:1;
unsigned int b6:1;
unsigned int b7:1;
} bits;
};
Now, we can access elements of the type ByteBitMap as byte values through the byte_value
member
ByteBitMap b;
b.byte_value = 59;
or bitwise through the bits stucture:
b.bits.b4 = 1;
Follow the link to find the complete example.
Sieve of Eratosthenes. Count all prime numbers less than 128,000,000. Hint: create a bitmap of 128M bits and use
each bit as an indication if the corresponding number prime or not.