Home arrow C++ arrow Page 5 - More on Handling Basic Data Types

More on Handling Basic Data Types

Have you ever wanted to learn how basic types of C++ variables interact in complex situations? Ivor Horton explains this, and also describes some interesting features of C++. This article is from chapter 3 of Ivor Horton's Beginning ANSC C++ The Complete Language (Apress, 2004; ISBN 1590592271).

Author Info:
By: Apress Publishing
Rating: 4 stars4 stars4 stars4 stars4 stars / 10
March 02, 2005
  1. · More on Handling Basic Data Types
  2. · Try It Out: Explicit Casting
  3. · Finding Out About Types
  4. · Try It Out: Finding the Sizes of Data Types
  5. · Using the Bitwise AND
  6. · Using the Bitwise Exclusive OR
  7. · Try It Out: Using the Bitwise Operators
  8. · More on Output Manipulators
  9. · Enumerated Data Types
  10. · Try It Out: Enumerated Data Types
  11. · The Lifetime of a Variable
  12. · Try It Out: The Scope Resolution Operator
  13. · Declaring External Variables

print this article

More on Handling Basic Data Types - Using the Bitwise AND
(Page 5 of 13 )

You’ll typically use the bitwise AND operator to select particular bits or groups of bits in an integer value. To see what this means, you can reuse the example presented at the beginning of this section, which used a 16-bit integer to store the characteristics of a font.

Suppose you want to declare and initialize a variable to specify a 12-point, italic, style 6 font—in fact, the very same one illustrated in Figure 3-1. In binary, the style will be 00000110, the italic bit will be 1, the bold bit will be 0, and the size will be 01100. Remembering that there’s an unused bit as well, you need to initialize the value of the font variable to the binary number 0000 0110 0100 1100.

Because groups of four bits correspond to a hexadecimal digit, the easiest way to do this is to specify the initial value in hexadecimal notation:

 unsigned short font = 0x064C;      // Style 6, italic, 12 

NOTE When you set up bit patterns like this, hexadecimal notation is invariably more appropriate than using decimal values.

To use the size, you need to be able to extract it from the font variable; the bitwise AND operator will enable you to do this. Because bitwise AND only produces 1 bit when both bits are 1, you can define a value that will “select” the bits defining the size when you AND it with font. All you need to do is define a value that contains 1s in the bit positions that you’re interested in, and 0s in all the others. This kind of value is called a mask, and you can define such a mask with the statement

 unsigned short size_mask = 0x1F;    // Mask is 0000 0000
         0001 1111 to select size

The five low-order bits of font represent its size, so you set these bits to 1. The remaining bits are 0, so they will be discarded. (Binary 0000 0000 0001 1111 translates to hexadecimal 1F.)

You can now extract the point size from font with the statement

 unsigned short size = font & size_mask;

Where both corresponding bits are 1 in an & operation, the resultant bit is 1. Any other combination of bits results in 0. The values therefore combine like this:

font                   0000 0110 0100 1100
size_mask              0000 0000 0001 1111
font & size_mask       0000 0000 0000 1100

Showing the binary values in groups of four bits has no real significance other than making it easy to identify the hexadecimal equivalent; it also makes it easier to see how many bits there are in total. As you can see, the effect of the mask is to separate out the five rightmost bits, which represent the point size.

You could use the same mechanism to select out the style for the font, but you’ll also need to use a shift operator to move the style value to the right. You can define a mask to select the left eight bits as follows:

 unsigned short style_mask = 0XFF00;   // Mask is 1111    
        1111 0000 0000 for style

You can then obtain the style value with the statement

 unsigned short style = (font & style_mask) >> 8; // 
        Extract the style

The effect of this statement is

font                     0000 0110 0100 1100
style_mask               1111 1111 0000 0000
font & style_mask        0000 0110 0000 0000
(font & style_mask) >> 8 0000 0000 0000 0110

You should be able to see that you could just as easily isolate the bits indicating italic and bold by defining a mask for each, with the appropriate bit set to 1. Of course, you still need a way to test whether the resulting bit is 1 or 0, and you’ll see how to do that in the next chapter.

Another use for the bitwise AND operator is to turn bits off. Part of the effect you saw previously is that any bit that is 0 in a mask will produce 0 in the result. To turn the italic bit off, for example, and leave the rest unchanged, you just bitwise-AND the font variable with a mask that has the italic bit as 0 and all the other bits as 1. You’ll look at the code to do this in the context of the bitwise OR operator, for reasons that I’ll explain next.

Using the Bitwise OR

You can use the bitwise OR operator for setting single or multiple bits. Continuing with your manipulations of the font variable, it’s conceivable that you would want to set the italic and bold bits on demand. You can define masks to select these bits with the statements

unsigned short italic = 0X40U;     // Seventh bit from 
        the right
unsigned short bold = 0X20U;       // Sixth bit from the

Now you can set the bold bit with the statement

font |= bold;                      // Set bold

The bits combine here as follows:

font                  0000 0110 0100 1100
bold                  0000 0000 0010 0000
font | bold           0000 0110 0110 1100

Now, the font variable specifies that the font it represents is bold as well as italic. Note that this operation will result in the bit being set, regardless of its previous state. If it was on before, it remains on.

You can also set multiple bits by ORing the masks together, so the following statement will set both the bold and the italic bit:

 font |= bold | italic;           // Set bold and italic

It’s easy to fall into the trap of allowing language to make you select the wrong operator. Because you say “Set italic and bold” there’s a temptation to use the & operator, but this would be wrong. ANDing the two masks together would result in a value with all bits 0, so you wouldn’t change anything.

As I said at the end of the last section, you can use the & operator to turn bits off— you just need a mask that contains a 0 at the position of the bit you want to turn off and 1 everywhere else. However, this raises the issue of how you specify such a mask. If you want to specify it explicitly, you’ll need to know how many bytes there are in your variable—not exactly convenient if you want your program to be in any way portable. However, you can obtain the mask that you want by using the bitwise complement operator on the mask that you would normally use to turn the bit on. You can obtain the mask to turn bold off from the bold mask itself:

bold                      0000 0000 0010 0000
~bold                     1111 1111 1101 1111

The effect of the complement operator is that each bit in the original is flipped, 0 to 1 or 1 to 0. You should be able to see that this will produce the result you’re looking for, regardless of whether the bold variable occupies 2, 4, or 8 bytes.

NOTE The bitwise complement operator is sometimes called the NOT operator, because for every bit it operates on, what you get is not what you started with.

Thus, all you need to do when you want to turn bold off is to bitwise-AND the complement of the mask, bold, with the variable, font. The following statement will do it:

 font &= ~bold;                // Turn bold off

You can also set multiple bits to 0 by combining several masks using the & operator, and then bitwise-ANDing the result with the variable you want to modify:

 font &= ~bold & ~italic;     // Turn bold and italic off

This sets both the italic and bold bits to 0 in the font variable. Note that no parentheses are necessary here, because ~ has a higher precedence than &. However, if you’re ever uncertain about operator precedence, put parentheses in to express what you want. It certainly does no harm, and it really does good when they’re necessary.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

blog comments powered by Disqus

- Intel Threading Building Blocks
- Threading Building Blocks with C++
- Video Memory Programming in Text Mode
- More Tricks to Gain Speed in Programming Con...
- Easy and Efficient Programming for Contests
- Preparing For Programming Contests
- Programming Contests: Why Bother?
- Polymorphism in C++
- Overview of Virtual Functions
- Inheritance in C++
- Extending the Basic Streams in C++
- Using Stringstreams in C++
- Custom Stream Manipulation in C++
- General Stream Manipulation in C++
- Serialize Your Class into Streams in C++

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 

Developer Shed Affiliates


© 2003-2019 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials