Bitmasks, and the bitwise operators, are something I've known about/can recognise, but had never actually needed to use them. The first time was when using Windows C++ APIs, and I tripped up over myself a few times trying to use it... So, here's what I wish I read at the start.

## tldr

• Add flags using OR `|`:
• `flags |= BORDER_LEFT`
• `flags |= BORDER_LEFT | BORDER_RIGHT`
• Remove flags using AND `&` with NOT `~`:
• `flags &= ~BORDER_LEFT`
• `flags &= ~(BORDER_LEFT | BORDER_RIGHT)`
• Toggle flags using XOR `^`:
• `flags ^= BORDER_LEFT`
• `flags ^= BORDER_LEFT | BORDER_RIGHT`
• Check any flag using AND `&`:
• `if (flags & BORDER_LEFT)`
• ```toCheck = BORDER_LEFT | BORDER_RIGHT; if ((flags & toCheck) != 0)```
• the result is non-0 if any of the flags match
• Check all flags using AND `&`:
• ```toCheck = BORDER_LEFT | BORDER_RIGHT; if ((flags & toCheck) == toCheck)```

See in Repl.it

## Flags

You'll often see bitmasks to used for "flags", for example:

``````BORDER_LEFT   = 0b0001 // 0b is the prefix for a binary number
BORDER_RIGHT  = 0b0010
BORDER_TOP    = 0b0100
BORDER_BOTTOM = 0b1000
``````

## OR (|)

The `|` (OR) operator sets a bit to 1 if either of the bits in that position are 1. We can use this to combine flags together:

``````BORDER_VERTICAL   = BORDER_TOP | BORDER_BOTTOM
//   0100
// | 1000
// = 1100

BORDER_HORIZONTAL = BORDER_LEFT | BORDER_RIGHT
//   0001
// | 0010
// = 0011

BORDER_ALL = BORDER_VERTICAL | BORDER_HORIZONTAL
//   1100
// | 0011
// = 1111

myBorders = BORDER_HORIZONTAL | BORDER_BOTTOM
//   0011
// | 1000
// = 1011
``````

## AND (&)

The `&` (AND) operator sets a bit to 1 if both bits in that position are 1. We can use this to check a flag:

``````flags = BORDER_TOP | BORDER_HORIZONTAL
// 0111

hasTopBorder = flags & BORDER_TOP
//   0111
// & 0100
// = 0100

hasBottomBorder = flags & BORDER_BOTTOM
//   0111
// & 1000
// = 0000
``````

See `hasTopBorder` becomes truthy (it's `0b100`, which is `4` in decimal, which is truthy), and `hasBottomBorder` becomes falsey (it's `0b0` which is.. `0`).

## NOT (~)

The `~` (NOT) operator flips the bits in each position. Anything which was 0 is now 1, and anything which was 1 is now 0.

``````BORDER_BOTTOM
// 1000

~BORDER_BOTTOM
// 0111

~~BORDER_BOTTOM
// 1000
``````

We can use this, alongside the `&` operator to remove a flag:

``````flags = BORDER_TOP & BORDER_RIGHT & BORDER_LEFT
// 0111

flagToRemove = BORDER_TOP
// 0100

flags = flags & ~flagToRemove
//   0111
// & 1011   <-- NOT (flip) of 0100
// = 0011
``````

We've removed BORDER_TOP from the bits.

## XOR (^)

The `^` (XOR) operator sets a bit if both bits in that position are different (i.e. only one side is 1). This can be used for toggling flags:

``````flags = BORDER_BOTTOM | BORDER_LEFT | BORDER_RIGHT
//   1000
// | 0001
// | 0010
// = 1011

flags = flags ^ BORDER_LEFT
//   1011
// ^ 0001
// = 1010

flags = flags ^ BORDER_LEFT
//   1010
// ^ 0001
// = 1011
``````

## Prefer videos?

Check out this video by The Cherno on YouTube:

Posted on
Written by Dan Harper
Tagged under