home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam ## 15.2. Bitwise Programming

Switching gears, let's examine an unrelated, esoteric topic -- bitwise programming with bitwise operators. This discussion was too obscure for Chapter 5, "Operators", but we'll cover it now for experienced programmers and braver beginners.

In order to track and manipulate a series of options in a highly optimized way, we can use the bitwise operators. Technically, the bitwise operators are mathematical operators, but they're typically used in a logical, not mathematical, context. Bitwise operators can access the individual binary digits (bits) in an integer. To understand how this works, you need to know how numbers are represented in binary format.

```1     // The base-10 number  1: (1 x 1) is 1
10    // The base-10 number  2: (1 x 2) + (0 x 1) is 2
11    // The base-10 number  3: (1 x 2) + (1 x 1) is 3
100   // The base-10 number  4: (1 x 4) + (0 x 2) + (0 x 1) is 4
1000  // The base-10 number  8: (1 x 8) + (0 x 4) + (0 x 2) + (0 x 1) is 8
1001  // The base-10 number  9: (1 x 8) + (0 x 4) + (0 x 2) + (1 x 1) is 9```

In binary, the columns we've been discussing are referred to as bits (short for "binary digit"). A four-bit number, for example, is a number with four digits (each of which may contain a one or a zero). The rightmost bit is considered bit 0; the bit to its left is bit 1, and so on. Following is an 8-bit number with a 1 in bits 0, 6, and 7; the bits are labeled above the number:

```bit: 76543210
11000001```

As with all numbering systems, the largest value for a single digit is one less than the base (also known as the radix). For example, in base-10 (decimal), the largest single digit is 9. Notice that because we're using 2 as our base, each binary digit must be either a or a 1. We know that the numbers 1 and are equivalent to the Boolean values true and false, so it is very convenient to use binary numbers as a series of on and off switches! That's precisely what the bitwise operators let us do.

Bitwise programming nearly always involves situations in which a series of properties can be turned on or off. Using bitwise operators, we can concisely represent many options within a single numeric value instead of using multiple variables. This provides better performance and lower memory consumption.

Suppose we're building a Flash site that sells cars. For the sake of simplicity, let's say there's only one kind of car for sale, but users can customize their car with any combination of four options: air-conditioning, a CD player, a sunroof, and leather seats. It's the job of our Flash program to come up with a total price for the car including all the options, and it's the job of a server-side program to track that information as part of the user's profile.

We could store the car's options with four separate Boolean variables, like this:

```var hasAirCon = true;
var hasCD = true;
var hasSunRoof = true;
var hasLeather = true;```

Essentially, we've got four switches -- one for each optional component of the car -- each requiring a variable. That works fine, but it means we need four variables in memory and four fields in the user-profile database on the server. When we record the car's options as individual binary digits, we can store all four options in a single 4-bit number: air-conditioning is bit (the 1's column), the CD player is bit 1 (the 2's column), the sunroof is bit 2 (the 4's column), and the leather seats are bit 3 (the 8's column). Here are some sample configurations that show how a single number can represent any combination of the four options:

```var options;
options = 1   // 1 is 0001; bit 0 is on: air-conditioning only
options = 2   // 2 is 0010; bit 1 is on: CD player only
options = 4   // 4 is 0100; bit 2 is on: sunroof only
options = 8   // 8 is 1000; bit 3 is on: leather seats only

// Here's the cool part: combining options
options = 5   // 5  is 0101: air-conditioning (1) and a sunroof (4)
options = 10  // 10 is 1010: CD player (2) and leather (8)
options = 15  // 15 is 1111: fully loaded baby!```

Whenever we want to add or remove options, we just add or subtract the value of the appropriate bit:

```var options = 0;  // No options to start
options += 4;     // Add sunroof (options is 4, or 0100)
options += 1;     // Add air-conditioning (options is 5, or 0101)
options += 2;     // Add CD player (options is 7, or 0111)
options -= 4;     // Remove the sunroof (options is 3, or 0011)
options += 8;     // Add leather seats (options is 11, or 1011)```

So now we know how to store multiple options as a series of bits in a single number. How do we examine those bits to calculate the cost of the car? We need to use the bitwise operators. We'll run through the operators first and come back to the car example after we're done.

### 15.2.1. Bitwise AND

A bitwise AND expression takes the form:

`operand1 & operand2`

The operands of bitwise AND can be any numbers, but they are converted to 32-bit binary integers before the operation occurs. If an operand has a fractional value such as 2.5, the fraction is discarded.

Note that the bitwise AND uses the single-character operator, &, and operates on the individual bits within its operands, whereas the logical AND operator discussed in Chapter 5, "Operators" uses the two-character operator, &&, and treats each operand as a whole.

Bitwise AND returns a number whose value is determined by comparing the individual bits in the numeric operands, operand1 and operand2, one at a time. If a bit contains a 1 in both operands, the corresponding bit will also be set to 1 in the result; otherwise, the bit will be a in the result.

Bitwise AND operations are most easily pictured by arranging the binary equivalents of the decimal operands vertically and lining up their bit columns. In this format, it is easy to tell which bits of the operands both contain 1s.

In this example, bit 2 (the third bit from the right) is 1 in both operands and is therefore set to 1 in the result. Other bits are set to in the result:

```1111
& 0100
------
0100```

In this example, bits and 3 are 1 in both operands and are therefore set to 1 in the result. Bits 1 and 2 are set to in the result:

```1101
& 1011
------
1001```

ActionScript uses decimal (base-10) numbers instead of binary numbers, which makes it harder to visualize bitwise operations. Here is what the previous operations look like in real code:

```15 & 4   // Result is 4
13 & 11  // Result is 9```

In practice, the bitwise AND operator is used to check whether a particular flag or set of flags (i.e., bits) is true or false.

The following example checks whether bit 2 (which has the value 4) is set to true:

```if (x & 4) {
// Do something
}```

Or, we can check whether either bit 2 or bit 3 (which has the value 8) is set to true:

```if (x & (4|8)) {
// Do something
}```

Note that the preceding example checks whether bit 2 or bit 3 is set using the | operator discussed next. To check whether both bits 2 and 3 are set, we can use:

```if (x & (4|8) == (4|8)) {
// Do something
}```

The bitwise AND operator is also used to set individual bits in a number to false; see Section 15.2.4, "Bitwise NOT" later in this chapter.

### 15.2.2. Bitwise OR

`operand1 | operand2`

The operands can be any numbers, but they are converted to 32-bit binary integers before the operation occurs. The fractional portion of an operand, if any, is discarded.

Note that the bitwise OR uses the single-character operator, |, and operates on individual bits within a number, whereas the logical OR operator discussed in Chapter 5, "Operators" uses the two-character operator, ||, and treats each operand as a whole.

Each bit in the result is determined by taking the logical OR of the bits of the two operands. Therefore, if a bit is set to 1 in either (or both) operand1 or operand2, that bit will be set to 1 in the result. Compare the following pseudoexamples to those shown earlier for the bitwise AND operator.

In this example, only bit 1 is set to in the result because bit 1 is in both operands. The other bits are set to 1:

```1101
| 0100
------
1101```

In this example, all bits are set to 1 in the result because each bit contains a 1 in at least one of the two operands:

```1101
| 1011
------
1111```

```13 | 4    // Result is 13
13 | 11   // Result is 15```

In practice, we often use bitwise OR to combine multiple numbers that represent individual options into a single numeric value that represents all the options of a system. For example, the following code combines bit 2 (value 4) and bit 3 (value 8):

`options = 4 | 8;`

The bitwise OR operator is also used to set an option to true in an existing value. The following example sets the option represented by bit 3 (value 8) to true. If the value in bit 3 is already true, it is untouched:

`options = options | 8;`

Multiple bits can also be set at once:

`options = options | 4 | 8;`

### 15.2.6. Bitwise Operations Applied

We began our look at bitwise operators using the example of a Flash site that sells cars. Now that we've seen how bitwise operators work, let's use them to determine the cost of a car, as shown in Example 15-3. You can download the .fla file for this example from the online Code Depot.

#### Example 15-3. Real-Life Bitwise Operations

```// First, set the options (usually by adding and subtracting numbers
// based on the selections of a fill-in form, but we hardcode them here)
var hasAirCon   = (1<<0)    // Bit 0: 0 means no, 1 means yes
var hasCDplayer = (0<<1)    // Bit 1: 0 means no, 2 means yes
var hasSunRoof  = (1<<2)    // Bit 2: 0 means no, 4 means yes
var hasLeather  = (1<<3)    // Bit 3: 0 means no, 8 means yes

// Now combine the options into a single number using bitwise OR
var carOptions = hasAirCon | hasCDplayer | hasSunRoof | hasLeather;

// Here's a function that calculates the price
function totalPrice(carOptions) {
var price = 0;
if (carOptions & 1) {  // If the first bit is set
price += 1000;       // add \$1000
}
if (carOptions & 2) {  // If the second bit is set
price += 500;        // add \$500
}
if (carOptions & 4) {  // If the third bit is set
price += 1200;       // add \$1200
}
if (carOptions & 8) {  // If the fourth bit is set
price += 800;        // add \$800
}

return price;
}

// Everything's set to go: let's call the function and see if it works!
trace(totalPrice(carOptions));  // Returns 3000. Cool...```

To avoid hardcoded bit values throughout your code, it's good practice to store the bit values corresponding to specific options in variables, such as:

```var airConFLAG   = 1 << 0;  // Bit 0, whose value is 1
var cdPlayerFLAG = 1 << 1;  // Bit 1, whose value is 2
var sunroofFLAG  = 1 << 2;  // Bit 2, whose value is 4
var leatherFLAG  = 1 << 3;  // Bit 3, whose value is 8```

Reader Exercise: Rewrite Example 15-3 using variables and the left shift operator instead of hardcoded bit values to represent the options.

### 15.2.6.1. Why bitwise?

Although Example 15-3 would be easier to understand as a series of Boolean operations, bitwise operations are extremely fast and compact. Anytime we can speak to a computer in its native binary tongue, we save room and gain speed.

For the sake of comparison, consider a situation in which we're tracking a user's profile, and each user has 32 settings that can be on or off. In a normal database, we'd need 32 fields for each user. If we have a million users, that's a million copies of 32 fields. But when we use bitwise programming we can store the 32 settings in a single number, requiring only one field in the database for each user! Not only does this save disk space, but every time we access a user's profile, we need transfer only a single integer, not 32 Boolean values. If we are processing millions of transactions, saving a few milliseconds per transaction can measurably improve system performance.

For further study, see Gene Myers' excellent article for C programmers, Becoming Bit Wise, posted at http://www.cscene.org /CS9/CS9-02.html. 