advertisement
Login | Register   
  Include Code  Search Tips
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Although the Standard Library has a bitset class, many programmers prefer to use bitwise operators directly. Do you wish to see a more user-friendly class that abstracts bitwise operations or is such a class uncalled for?
Partners & Affiliates
advertisement
advertisement
advertisement
advertisement
Average Rating: 3.3/5 | Rate this item | 9 users have rated this item.
Bitwise Operators: Combining Efficiency and Ease of Use (cont'd)
Self-assignment
In addition to the basic four operators shown, C++ defines three self-assigning versions thereof:
  • &= self-assigning bitwise AND
  • |= self-assigning bitwise OR
  • ^= self-assigning bitwise XOR

Thus, the previous code listing can be rewritten like this:


BYTE s1=63; // 0x3f, 0011 1111
BYTE s2=67; // 0x43, 0100 0011
s1^=s2; // equivalent to: s1 = s1 ^ s2
advertisement
Shifting
Two additional operators are left shift and right shift:
  • << left shift
  • >> right shift
>> shifts bits by n positions to the right. For example, if you take the string:

0011 1111 //decimal value: 63
Shifting it by one position to the right produces:

0001 1111 //decimal value: 31
BYTE s1 = 63; //0x3f, 0011 1111
BYTE result =
s1 >> 1; // 0x1f, 0001 1111
A graphic illustration of this operation may demystify the underlying steps. First, you have an eight bit string whose boundaries are marked with a pair of bars:

|0011 1111|
The right shift operation causes the leftmost bit's position to become empty (indicated by an underscore). The rightmost bit overflows outside the string's boundaries:

|_0011 111|1
In the second step, the processor pads empty positions with zeros and discards bits that were pushed outside the string's boundaries (this rule applies only to unsigned types; the effect of shifting signed values is machine-dependent):

|00011 111|_
Of course, these steps don't necessarily correspond to the underlying machine instructions that your processor employs but the effect is the same. Bit shifting happens to be a very efficient operation. This is why time-critical applications often use shift operators as a faster alternative to the division and multiplication operators. In the above example, the shift operation has the same effect as dividing the original value by two. In a similar vein, you can get the effect of multiplying a number by two if you apply the left shift operator. For example, left shifting the number 63 by one position produces 126:

BYTE s1 = 63; // 0x3f, 0011 1111
BYTE res = s1 << 1; //dec 126, 0x73, 0111 1110
Using the self-assignment versions of these operators, the previous code can be rewritten like this:

BYTE s1 = 63; //0x3f, 0011 1111
// the expression 's1 >> 2;' divides s1 by 4
s1 >>= 2; // 15, 0x0f, 0000 1111
Wise Up
Bitwise operators are useful in bit masking, i.e., setting or examining bits in a bit string. Take for example a simple word processing application. The text in a document (or a portion thereof) may have the following features: bold, italics, underlined, or none. Each of these features can be represented as an individual bit:

const BYTE BOLD = 0x01; // first bit
const BYTE ITAL = 0x02; // second bit
const BYTE UNDERL = 0x04; // third bit
Users may combine some of these features, all of them or none:

BYTE style = BOLD | ITAL;//turn on bold and italics
The following code tests whether underline and bold are on using bit masks:

bool isul=style & UNDERL; // false
bool isbold=style & BOLD; // true
Previous Page: Operators' Functionality  
Danny Kalev is a system analyst and software engineer with 13 years of experience, specializing in C++ and object-oriented analysis and design. He is a member of the ANSI C++ standardization committee and the author of ANSI/ISO C++ Professional Programmer's Handbook (Que, 1999, ISBN: 0789720221). Reach him at dannykk@inter.net.il.
Page 1: IntroductionPage 3: Self-assignment
Page 2: Operators' Functionality 
Please rate this item (5=best)
 1  2  3  4  5
advertisement