# Bitwise Operators

As the name implies, bitwise operators look at the individual bits of a number. Computers store everything in binary, therefore bitwise operations can be used on all types of data, whether the source code displays the data in binary or not. The computer will look at those numbers' binary representations to calculate the result.

## AND

Bitwise `AND`, often abbreviated to `&`, compares each individual bit of two different numbers, and outputs a 1 if they are both 1, and 0 otherwise.

```    10101101
AND 00110010
------------
00100000
```

A few properties of `AND` that aren't readily apparent. For all numbers A:

• `A & 0 = 0`
• `A & A = A`
• `A & -1 = A (remember that -1 = FF)`
• Every 4 binary digits of A and B can be `AND`ed separately and concatenated, and the result is the same.

For example, `0x37 & 0x49 = ((0x30 & 0x40) | (0x07 & 0x09))`

### Filtering

`AND` is useful for filtering out unwanted bits for a comparison. A practical example is checking whether a number is odd or even. This uses the property that the least significant bit of all even numbers is 0, and all odd numbers is 1. <lang C>if ((foo & 1) == 0) {

```  // your code for what happens when foo is even goes here
```

} else {

```  // your code for what happens when foo is odd goes here
```

}</lang>

Filtering is also useful for checking the status of a flag variable, where each bit represents a different options setting. This example is for 6502 Assembly. <lang 6502asm>FLAG_SCROLL equ %10000000 ;0 = no scrolling, 1 = scrolling enabled.

```                         ; This label represents a constant so that we don't have to remember what the flags mean.
```

LDA statusFlags ;get the variable statusFlags, an 8 bit value where each bit controls a different aspect of our program. AND #FLAG_SCROLL ;AND statusFlags with the binary value 0b10000000 (decimal 128) BNE ScrollScreen ;the corresponding bit of statusFlags was set, so allow the screen to scroll.</lang>

### Random Chance

Given the output of a random number generator with all equally likely outcomes, you can use `AND` with that output to create random occurrences. If ${\displaystyle n}$ is a power of 2, then to create a random event with probability ${\displaystyle 1/n}$, you just need to `AND` the RNG output with ${\displaystyle n-1}$. In the example below, `rand` is a randomly generated number. Its size doesn't change the probabilities listed below.

<lang C> if ((rand & 3) == 0) {

```  //1 in 4 chance of occurring
```

} else {

```  //3 in 4 chance of occurring
```

}

if ((rand & 15) == 0) {

```  //1 in 16 chance of occurring
```

} else {

```  //15 in 16 chance of occurring
```

}</lang>

## OR

Bitwise `OR`, often abbreviated to `|` (SHIFT+\), compares each individual bit of two different numbers, and outputs a 0 if both are 0, and a 1 otherwise.

```    10101101
OR  00110010
------------
10111111
```

When we say "or" in the English language, we usually mean "one or the other, but not both." This isn't the case in programming. That's actually a different operator which will be covered later.

A few properties of OR that aren't readily apparent. For all numbers A:

• `A | 0 = A`
• `A | A = A`
• `A | -1 = -1`

The first property implies that if a subset of a byte is a sequence of zeroes, then `OR`ing that sequence of zeroes with any bit combination will result in the same bit combination. For example:

```%11 000 111 | %00 101 000 = %11 101 111
%11 000 111 | %00 111 000 = %11 111 111
%11 000 111 | %00 001 000 = %11 001 111
```

etc.

### Failsafes

Bits that get `OR`ed with 1 always equal 1, regardless of their original value. If you have a variable that you want to guarantee at least certain bits are set, you can OR them with those bits. The nice thing about this method is that the actual value of that variable need not be compared to anything. Those bits will get set either way.

### Combining two values without addition

If you have two values in separate "nibbles", e.g. `0xFF00` and `0x00DD`, then an `OR` of these two will combine them, e.g. `0xFFDD`. This is just an extension of the property that `A | 0 = A`.

## XOR

eXclusive OR, often abbreviated to `XOR`, `^` or called `EOR` in some languages, compares each individual bit of two different numbers, and outputs a 1 if they are different and 0 if they are the same.

```     10101101
XOR  00110010
------------
10011111
```

A few properties about `XOR` that aren't readily apparent:

• If `A XOR B = C`, then `A XOR C = B` and `B XOR C = A`.
• A bit `XOR`'d with 1 will flip. A bit `XOR`'d with zero won't change.
• A bitwise `NOT` is the same as `XOR -1`.
• `A ^ A = 0`. Furthermore, if `A ^ B = 0`, then `A = B`.
• If `((A ^ B) & C) = 0`, then A and B both share the bits of C in common.

### Toggling

A flag register `XOR`'d with a given value will flip those particular bits, and leave the rest alone.

## NOT

A bitwise `NOT`, or `~` takes one number as an argument and flips all its bits. This has its uses, especially when reading video game controllers, but is a little more limited than the others.

Among `AND`, `OR`, `XOR`, and `NOT`, only `XOR` and `NOT` are reversible.

## Citations

1. [Beyond 8-Bit Unsigned Comparisons by Bruce Clark]