This started off as a post about using bitmasks with SceneKit for collision detection/notification but the explanation of bitwise operators became so extensive I’ll have to talk about how this ties to SceneKit in another posting.

To understand bitmasks and bitwise operations I think it’s essential to understand how binary numbers work, don’t worry it’s pretty simple. As you know a computer is a digital device which means it basically is on or off and at its lowest level that is how all data is stored, a one or a zero. This unit of data (a single one or zero) is called a bit. Obviously there’s not much you can do with just one bit when it comes to representing numbers but when you combine 8 bits you get a byte and now you can start representing things, such as any number from 0-255.

Here’s how that works – when you have a byte with a series of 8 bits that are one or zero imagine it like this: (Think of these as 8 ‘lanes’ of bits.)

That is a zero, nothing is going on here. Now what if we change the bit on the right to a 1? (you will need to learn to read these right to left)

This is now representing the number 1. So if we turn on the next bit what do we have?

You know what that is? It’s a 3. But why? You remember how I mentioned thinking of these a ‘lanes’, well imagine each lane has a number assigned to it, starting at the right and working to the left:

Notice we numbered the lanes by doubling the previous value, also notice if you add the lanes at are ‘on’ (lanes 1 and 2) you get 3. Using this you can also represent a two like so:

Using this we can see the largest number we can represent with 8 bits is 255:

That is an 8-bit, unsigned (all positive, no negative) integer value. You can see where increasing the number of bits can improve the representation, for example a 16-bit integer would be able to represent numbers up to 65,535 – yeah that escalated quickly.

Lane #: 32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1

What cool stuff can you do with this knowledge? Well as you noticed, the lane numbers double each time so by ‘shifting’ right or left you get quick multiplication and division, for example if you have 2:

Now, if we move all those bits to the left by one, you get 4:

Note that any numbers shifted beyond the bounds of this variable (in this case an 8-bit unsigned integer) will be discarded in Swift. So shifting 128 left by one makes it zero.

Inversely, you can also right shift. For example, if you have 16 and shift to the right by 2 you end up with 4:

In Swift you can do something like this:

var a = 8 //a is 8

var b = a >> 1 //b is 4 (8 shifted to the right by 1)

var c = a << 2 //c is 32 (8 shifted to the left by 2)

You can also create a number with its binary representation:

var w = 0b00000010 //w is 2

Now, for more fun you can use bitwise operators like a bitwise OR which combines two numbers into a new one:

As you can see, if a lane has a 1 in the first number OR the second, that gets put in the new number.

In Swift, it might look like this – notice the type of ‘UInt8’ and bask in your knowledge of what that means:

var y:UInt8 = 0b10000110 //y is 134

var w:UInt8 = 0b00000101 //w is 5

var a:UInt8 = y | w //a is 135

In addition to OR, you can use a bitwise AND operator, in which only lanes that have a 1 in both inputs will be carried over:

Which in Swift could look like:

var y:UInt8 = 0b10000110 //y is 134

var w:UInt8 = 0b00000101 //w is 5

var a:UInt8 = y & w //a is 4

There is also an XOR operator and more things you can do with this knowledge in Swift, and for that I will refer you to Apple’s documentation on Advanced Operators. Now we have covered a low-level topic to work with a high level framework (SceneKit) I hope to post about how bitmasks come into play soon!