>> Bitwise Shifting (swift 3) <<

The advanced operators “<<” and “>>” are used in swift to shift the bites in an integer a given number of times. Shifting a bit to the right has the effect of halving the integer while shifting it to the left doubles it. For example:

// Shifting Right
let example1 = 8 >> 1 // example1 == 4
let example2 = 8 >> 2 // example2 == 2
// Shifting Left
let example3 = 8 << 1 // example3 == 16
let example4 = 8 << 2 // example4 == 32

To understand whats going on with bit shifting, we first need to understand how integers are represented in binary. In this example I will use an Unsigned 8 bit integer to demonstrate how this works.

Understanding UInt8

I’m using UInt8 in my example because it will be the fairly simple to understand since we are not dealing with negative numbers and only 8 bits.

note: having a signed integer basically means one bit in the binary signature is being used to signify weather the integer is positive or negative. Meaning we only have 7 remaining bits to define a number. This makes bit shifting significantly more complicated. In an unsigned integer all 8 bits can be used to define the number.

having 8 bits to represent a number means we can represent 256 different possibilities (0–255).

0 = 00000000    2 = 00000010    4 = 00000100      8 = 00001000       
1 = 00000001 3 = 00000011 5 = 00000101 9 = 00001001
6 = 00000110 10 = 00001010
7 = 00000111 11 = 00001011
12 = 00001100
13 = 00001101
14 = 00001110
15 = 00001111

                                                 16 = 00010000
...
32 = 00100000
...
64 = 01000000
...
128 = 10000000
...
255 = 11111111

I’m not going to write out all 256 representation but you should see a pattern here. At the start of each column 2, 4, 8, 16, 32, 64, and 128 represent places where another bit is required. Notice each number in the sequence is doubled from the previous number. Once we hit 255 we would need a 9th bit to represent the number 256… so in this case that is the highest number UInt8 can represent.

Bitwise Shifting

Now lets take a look at bitwise shifting using one of these numbers.

For each shift imagine all the bits in the 8 bit sequence being pushed over by one space. Imagine the bits are sitting on a table but there is only enough space for 8 of them. If we push them to the right the right-most bit will fall off the table and there will be an empty space now on the left side of the table. That empty space gets filled by a zero and we have our new value.

let num = 8                   // 00001000
let shiftedNum = num >> 1     // 00000100  0      
^ ^
inserted 0 0 bumped off
// shiftedNum = 4                00000100

And if we were to shift to the left the value would be doubled

let num = 8                   // 00001000
let shiftedNum = num << 1     // 0  00010000      
^ ^
0 bumped off inserted 0
// shiftedNum = 16            // 00010000

Here are a couple more examples!

let num = 25 << 2  // 00011001 (2 shifts left)> 01100100, num == 100
let num2 = 30 >> 5 // 00011110 (5 shifts right)> 00000000, num2 == 0

One situation to note is if the bit shift causes the value to go above 255 we will see some unexpected results. Since there are only 8 bits we can’t add a 9th to make the value greater than 256. Say we shift the 200 once to the left expecting to double it… this would be the result.

let num = 200 << 1 // 11001000 (1 shift left)> 10010000, num == 144

Also not that shifting right can happen as many times as you like… but once you hit zero the number will stay as zero for the remaining shifts.

let num = 10 >> 10 // 00001010 (10 shifts right)> 00000000, num == 0

Using Bit shifting to Find RGB values in a Color Hex Code

Here is a more practical and complex example of how bitwise shifting can be useful. Understanding this solution requires us to know a little bit about hexadecimal notation.

Hexadecimal is a number system with a base of 16 (decimal is a base of 10). We can nicely represent the numbers 0–15 using 4 bits.

In swift, using hexadecimal notation gives us a single integer, but when we using a hexadecimal notation to get the red, green, and blue values of a color we need to be able to isolate 3 numbers out of the single integer. Lets look at a color in a color editor and break it down.

We have this yellow color with the following values.

red = 255
blue = 193
green = 7
hex color # = FFC107

But if we were to only provide the hex code as an input we would only see a large integer.

So what we need to do is to somehow isolate FF, C1, and 07. First lets take a look at the binary of this hex code.

F    F    C    1    0    7
1111 1111 1100 0001 0000 0111

Using the & operator we can effectively mask any piece of the hexadecimal with 0’s. The way that the & operator works is it compares the 2 binary signatures and wherever they both have a one, the one is maintained - Wherever there is a zero, the zero is maintained. This might help visualize

let isolatedGreenValue = 0xFFC107 & 0x00FF00
F    F    C    1    0    7
1111 1111 1100 0001 0000 0111
&
0    0    F    F    0    0
0000 0000 1111 1111 0000 0000
=
0    0    C    1    0    0
0000 0000 1100 0001 0000 0000

Now that we almost have the green value figured out. Only using the & operator we are able to isolate the value but now we need to shift it! Can you guess how many times we need to shift the bit over and in what direction?

0    0    C    1    0    0
0000 0000 1100 0001 0000 0000
>> 8
=
0    0    0    0    C    1
0000 0000 0000 0000 1100 0001

Since there are 8 bits on the right side of c1 if we shift it over 8 times we will get the green value! (same as the green value in the screenshot above)

Hopefully you have found this post informative! Here is a completed function showing how to get the RGB values from a hex color code using & operator and bit shifting.

Thanks for reading :)