# Bitwise Operations

Summary and demonstration of all the usual bit operations in C.

## Notes

Manipulating individual bits of a variable or register is very common especially in embedded programming. If you studied any digital/boolean logic, the theory may be familier, but we faced with actually writing a line of bit manipulation code I often find myself mentally working it out again from first principles.

Here’s a catalog of the conventional bit operation techniques in C. Note: bitfields provide another approach for dealing with fixed size data, but I’ll cover those seperately

### Building blocks

The key operators from which all these recipes can be made:

- bitwise OR:
`|`

- bitwise AND:
`&`

- bitwise XOR:
`^`

- bitwise NOT:
`~`

to invert (ones’ complement) - shift:
`<<`

,`>>`

to shift bits left or right - assignment:
`=`

but often compounded with a bitwise operation e.g.`|=`

,`&=`

,`^=`

,`~=`

Note: bitwise operators are not to be confused with their logical analogs: `||`

, `&&`

, `!`

.

### Setting a bit

Shift a bit to the desired position to be set and OR it with the current value. e.g. to set bit position p:

```
value |= 1 << p;
```

### Clearing a bit

Create a bit mask with all bits set to 1 except those to be cleared. AND this with the current value to clear all the unmasked bits e.g. to clear bit position p:

```
value &= ~(1 << p);
```

### Toggle a bit

Shift a bit to the desired position to be toggled and XOR with the current value.

```
value ^= 1 << p;
```

### Checking a bit

Shift a bit to the desired position to be checked and AND with the current value. The result will be non-zero of the bit is set.

```
value & (1 << p)
```

To coerce to a boolean result, compare with 0 (for example:

```
value & (1 << p) == 0
```

### Setting multiple bits

Setting multiple bits poses the challenge that some bits may need to be set, some cleared, all while keeping the other bits as-is.

There are a few ways to approach this. Here’s one: mask out the bits to be set in the current value, then OR with the new bits (shifted into the correct position)

For example, to set two bits[3:2] with some `some_bits`

value:

```
new_bits = 0b10;
result = (value & ~(0b11 << 2)) | (new_bits << 2);
```

### Macros

Libraries often provide macros for bit operations, though these are non-standard and often not portable. Here are some commmon ones:

The `_BV`

“bit value” - shortcut for creating a 1-bit mask. e.g. avr/sfr_defs.h

```
#define _BV(bit) (1 << (bit))
```

### Running the Examples

See example.c for details. A makefile compiles and runs:

```
$ make
gcc -Wall -O0 example.c -o example
./example
===== test_bit_set
Initial value : 0b11110000
Result of setting bit 3 : 0b11110100
===== test_bit_clear
Initial value : 0b10101111
Result of clearing bit 2 : 0b10101011
===== test_bit_toggle
Initial value : 0b10101111
Result of toggling bit 2 : 0b10101011
After again toggling bit 2 : 0b10101111
===== test_bit_check
Initial value : 0b11110000
Test if bit 2 set : 0b00000000
Test if bit 6 set : 0b00000001
===== test_bit_set_multiple
Initial value : 0b11110000
Bits to set at position 5:2 : 0b1010
Result : 0b11101000
NB: bit positions mentioned are 0-based from LSB
```