Bitwise Operations, the basics

I'm a software developer and computer scientist who loves building things.
Search for a command to run...

I'm a software developer and computer scientist who loves building things.
No comments yet. Be the first to comment.
The Interface Segregation Principle is the I in SOLID design principles. It states that types should not implement methods unrelated to their operations. In essence, interfaces should be designed so that the implementing types are not forced to imple...

The project management iron triangle applied to software development
Errors in golang are vastly different from errors in JavaScript. In this post, we will implement error handling for the events project we started building in the first post . That means, handling errors within the module itself as well as errors fr...

If you already know how to use a programming language, when learning a new language it is only natural to attempt to draw comparisons. This post is the first in a series, we'll attempt to learn Golang by re-implementing Events APIs in Go. What are th...

This post is inspired by this wonderful post by Evelyn Stender. This post does not explain what a generator is or basic usage, Evelyn's post does a good job of that. Instead, in this post, we will demonstrate how generators can be useful for streamin...

Many developers don't bother with bitwise operators, mostly because people don't know them well enough. There is also the argument of where they fit in everyday programming, like web development. There is a high likelihood people will confuse a & b for a && b, the first will treat operands as bits (32 bits to be precise) and the second is your everyday Boolean operation.
A quick refresher on truth tables is in order here, to fully understand bitwise operators. For the sake of simplicity and brevity, let's focus on the most important 2, AND and OR (click here to learn more).
Assuming we have two operands each having a single bit (1 or 0), this operator will return 1 if and only if both operands are 1s. Common operators used to denote the AND operation are ∧, K, & and ⋅.

To put it in simpler terms, if A and B are both 1 then the result is 1, if either operand is not 1 the result is 0.
Using the same variable as the AND example, the OR operator will return 1 either on or the other operand is 1.

First things first, those operators also work on operands with more tha one bit, for example, 1010 & 1000 = 1000 or 1010 | 1000 = 1010. Note that this operation is not performed as a sequence of bits (0s and 1s) and not decimal or some other number notation.
Now, let's assume JavaScript is your programming language of choice (this works for other languages, check docs). It is quite easy to perform bitwise operations on numbers and use this as a way of making your code more efficient and easier to work with.
const variable = 8;
variable.toString(2); // result is 1000
If we wanted to build a simple ACL. Typically, you would create a list of permissions (for example, Create, Read, Update and Delete) and create a role that you could assign to a user.
// permissions
const permissions = {
create: CREATE,
read: READ,
update: UPDATE,
remove: DELETE. // delete is keyword in JavaScript
}
const AdminRole = ['CREATE', 'READ', 'UPDATE', 'DELETE'];
const Admin = {
name: "Super Admin",
role: AdminRole,
// other fields
}
function createAndReadPost(post, role) {
if (!role.includes('CREATE')) {
throw new Error("Not authorized");
}
// create post
if (!role.includes('READ')) {
throw new Error("Not authorized");
}
// read post
}
createAndReadPost(postObject, admin.role);
This will work, but can get complicated quickly especially if we need to combine permission this way. Let's not get started on how much storage this will consume if you were building something like a CMS. Enter bit field flags. It is possible to represent these permissions using bits.
const CREATE = 1; // 0001
const READ = 2; // 0010
const UPDATE = 4; // 0100
const DELETE = 8; // 1000
const AdminRole = CREATE | READ | UPDATE | DELETE; // 1111
const Admin = {
name: 'Super Admin',
permissions: AdminRole,
};
function createAndReadPost(post, role) {
if (CREATE & (role === 0)) {
throw new Error('Not authorized');
}
// create post
if (READ & (role === 0)) {
throw new Error('Not authorized');
}
// read post
}
createAndReadPost(postObject, admin.permissions);
Quick comparison, "READ" is 4 bytes and in the bitwise example AdminRole, with all four permissions is 32 bits. There is the case of bitwise operations also being multiple times more efficient that string comparison.
There are many other use cases for bitwise operations, they can be very powerful tools to add efficiency and improved readability to your programs. Not to mention there are many other bitwise operators not covered in this post.