DEV Community

Thomas Klein
Thomas Klein

Posted on

JavaScript and bit masks

Even though you can use bit masks in JavaScript they are not widely (if at all) known. If you don't know what bit masks are, and want to learn a little bit about programming history, this post is for you:

Introduction

The primary use case for bit masks is to save memory. They come from a time where memory was scarce, long before the internet.
Programmers back then stored multiple values into a single value. How did they do this? With bit masks.

They took advantage that the computer uses bits. 1 bit just stores 0 or 1. You might as well think of it as set or unset, true or false or simply a flag.

If you have 2 bits you can store them in 4 ways, this could be 4 different flags:

Bit2 Bit1
0 0
0 1
1 0
1 1

If we have 3 bits we can store them in 8 different ways:

Bit3 Bit2 Bit1
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

They follow a power of two:
2bit -> 2^2 = 4
3bit -> 2^3 = 8
32bit -> 2^32 = 4 294 967 296
and so on.

Unfortunately if you wanted to have a flag in your code, a true-false value, early computer systems didn't allow you to just use 1 bit to specify that flag. For the sake of this introduction the computer always allocated 4bits for every kind of variable.

Since you only want to store a flag that theoretically only needs 1bit the remaining 3bits are going to waste.

If you add yet another flag, you will again allocate 4bits where 3bits are wasted.
So now you wasted 6bits because you created 2 separate flags.
This was a huge deal back in the day.

The solution to this problem was to store the 2 flags(2bits) not as separate variables but inside a single (4bit) variable. This way we only waste 2bits out of 4bits in this concrete example.

Bit Operators

To achieve this you have to use bit operators. I'm sure you've already seen || or && in action in some JavaScript code so you know they relate to logical or and logical and.

But did you know there is also this syntax?:

let or = var1 | var2;
let and = var1 & var2;

They operate on a bit level and are the whole secret to bit masks.

& (AND)

Given 2 bit sequences they produce the following output:

0 1 0 1 1
1 1 0 1 0
..............
0 1 0 1 0

If both are 1, the output will also be 1.
If only one of them is 1 it will be set to 0.

| (OR)

Given 2 bit sequences they produce the following output:

0 1 0 1 1
1 1 0 1 0
..............
1 1 0 1 1

If at least one of them is 1, the output will also be set to 1.

This is all you need to know to work with bit masks.
Pretty similar to logical AND and logical OR.
To enter an if clause with logical AND (&&), both conditions need to be true.
To enter an if clause with logical OR (||), only 1 condition needs to be true.

Example

Say we want to have a simple permission system that differentiates between a user and admin.

We can specify the bit sequences as follows:

Bit2 Bit1 Permission
0 0 Unused
0 1 User
1 0 Admin

The person is a user, if the bit sequence is 01.
The person has admin rights, if the bit sequence is 10.

With this info we can create our bit masks in JavaScript, we can specify the binary value right away with binary literals:

const USER = 0b01;
const ADMIN = 0b10;

Lets create a permission that specifies that someone is a user and admin:

let userPermission = USER | ADMIN;

Notice the | operator to set values.
This is the "store 2bits in 1 variable" that I talked about before.
Now userPermission contains info whether USER is set and whether ADMIN is set.

But how do we check the permission? With the & operator:

if((userPermission & ADMIN) === ADMIN) {
  //confirmed admin
}

How did this work?
Let's look at the & operation:

1 1 //userPermission
1 0 //ADMIN
.....
1 0

We get the bit sequence 10, then we check if this sequence matches ADMIN and yes it does, thus we are confirmed admin :)

To check for a user we use the same pattern:

if((userPermission & USER) === USER) {
  //confirmed user
}

That's how programmers back in the day tried to save memory, while it's not that useful on the web today due to the way JavaScript works and overall technological advancements it's always nice to know the history of things.

If you're feeling intrigued, here's more info about bit operators (in JavaScript): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
I only covered the very top, there are more operators that allow more use cases but that would exceed the scope for this post.

Top comments (0)