2010.12.08

Using integers to store multiple boolean values

Before starting I have to say that I come from a design background and not so long ago I didn’t know anything about bitwise operations, in fact I didn’t even know that it existed, the content described on this post should be trivial for developers coming from a computer science background or low-level languages…

The intention of this post is not to teach what each bitwise operator does, in fact I’m going to explain how to use it without telling what it does since I think it may be easier to understand. The main reason for writing this post is because I had to explain this technique to a couple of different friends over the past years (or at least I tried…) and also because I believe that most front-end developers don’t know about it.

I think I’ve learned it around 3 years ago when I was planing to code a multiplayer RPG game with a couple of friends and was doing some research about ways to optimize data transfer, that was probably the first time I saw a real use for bitwise operations on high-level programing besides splitting color channels…

Use cases

A common use for this technique is to store multiple settings that can be mixed and matched together, it can help reduce the amount of memory / bandwidth required to store / process / transfer the information and it also simplify some operations… PHP uses this technique for the error reporting settings. – if you think about it on an abstract way, every single operation that a computer does is a series of bitwise operations, but that isn’t important right now, the important is to understand how to use it on a high-level context and when…

Example

I’m not going to explain what each bitwise operator does, I believe that just looking at the example may be enough to understand what is going on and trying to explain bitwise operators may be an overhead since you don’t need to know that much to use it on this specific context.

I’ve decided to use a simple user permission system as example because I think it is going to be easier to understand (since variable names are easy to understand and makes sense), it was written in JavaScript but can be easily ported to other languages. The comments after each line represents the variable value or console.log output:

//--- Masks ---//

var vote = 1 << 0; //1
var add = 1 << 1; //2
var remove = 1 << 2; //4
var manage = 1 << 3; //8
var comment = 1 << 4; //16
var publish = 1 << 25; //33554432

//--- Sets ---//

var user1 = vote | remove | manage; //can "vote", "remove", "manage"
var user2 = user1 | publish; //all `user1` plus "publish"
var user3 = user2 ^ manage; //all `user2` minus "manage"

//--- Matches ---//

console.log("USER 1 : "+ user1); //13

console.log(user1 & vote); //1 : TRUE
console.log(user1 & add); //0 : FALSE
console.log(user1 & remove); //4 : TRUE
console.log(user1 & manage); //8 : TRUE
console.log(user1 & comment); //0 : FALSE
console.log(user1 & publish); //0 : FALSE

console.log("USER 2 : "+ user2); //33554445

console.log(user2 & vote); //1 : TRUE
console.log(user2 & add); //0 : FALSE
console.log(user2 & remove); //4 : TRUE
console.log(user2 & manage); //8 : TRUE
console.log(user2 & comment); //0 : FALSE
console.log(user2 & publish); //33554432 : TRUE

console.log("USER 3 : "+ user3); //33554437

console.log(user3 & vote); //1 : TRUE
console.log(user3 & add); //0 : FALSE
console.log(user3 & remove); //4 : TRUE
console.log(user3 & manage); //0 : FALSE
console.log(user3 & comment); //0 : FALSE
console.log(user3 & publish); //33554432 : TRUE

Flags

On the example above the variables vote, add, remove, manage, comment, publish are flags. A flag is a "kind of ID" (in fact it is an integer) that represents the position of a specific boolean value. A flag value should be 2 power of N where N is 0...31 (ie. 1, 2, 16, 64, 512, 4096...). Flags doesn't need to follow a specific order, they can be mixed/matched as desired and skip as many numbers as you want.

"Sets"

What I'm calling a "set" is in fact a group of booleans. The vars user1, user2, user3 represent users with different kind of permissions, as you can see it is pretty simple to combine multiple options and create a custom set that only contain the ones you want (for me this is the biggest advantage of using this approach for storing settings). You can store up to 32 boolean values/flags in a single 32-bit number (1 << 31).

Matches

Bitwise operations used to check if the "set" contains a "flag". If the result of the AND bitwise operation between the "set" and "flag" is different than zero it means that the "set" contains the "boolean value".

Conclusion

This is a very useful technique when dealing with a large number of options that needs to be combined/extended or when memory usage is a huge concern (in most cases it isn't), the main drawback of using it is that most developers don't know how to use bitwise operators so it can reduce the code readability/maintainability a lot.

The most important thing is to identify when this is the proper approach for a problem, sometimes it can save a lot of work and make some tasks way easier but most people can get around without never actually using it (for the kind of stuff I usually code it is really uncommon to find a problem that requires it). Don't use it blindly, know why you are doing it and consider different approaches before making your decision.

Remember that you can use the same technique to store any kind of data, not only boolean values, color channels are stored exactly the same way, each color is just an integer that contains multiple integers inside of it:

var color = 0xff00cc; //hexadecimal color (0...16,777,215)
var r = color >> 16; //red channel (0...255)
var g = color >> 8 & 0xff; //green channel (0...255)
var b = color & 0xff; //blue channel (0...255)

Tip

The methods toString() and parseInt() are your best friends, if I knew how to use it properly when I was learning bitwise operations everything would be way easier.

parseInt("10101", 2); //21
(21).toString(2); //"10101"

parseInt("0xff00ff", 16); //16711935
(16711935).toString(16); //"0xff00ff"

Further reading


Comments

"developers don't know how to use bitwise operators", yes it is a problem. bitwise operators a useful in so many situations.

This is a fantastic way to store permissions. Bitwise operations are fast and easier than if-else to find out is your users have permission for a function.

Only catch is that you have to decide if it's going to be a 32bit or 64bit application (for obvious reasons :))

[...] // !!!EDIT!!! http://blog.millermedeiros.com/using-integers-to-store-multiple-boolean-values/ [...]

Thank you very much, it has been a "few" years since I used binary and your article was more than helpful.

Leave a Comment

Please post only comments that will add value to the content of this page. Please read the about page to understand the objective of this blog and the way I think about it. Thanks.

Comments are parsed as Markdown and you can use basic HTML tags (a, blockquote, cite, code, del, em, strong) but some code may be striped if not escaped (specially PHP and HTML tags that aren't on the list). Line and paragraph breaks automatic. Code blocks should be indented with 4 spaces.