While perusing Apple’s Swift language guide, I came across an interesting section regarding bit manipulation. Unbeknownst to me, Swift sports the same bitwise and bit shifting operators used by both C and Objective-C. Here’s a recap:
AND
The Bitwise AND &
operator combines the bits of two
numbers, maintaining the value of 1 for each bit ONLY if they are both
1.
let firstAND: UInt8 = 0b11110000
let secondAND: UInt8 = 0b00001111
let thirdAND: UInt8 = 0b00000001
let firstANDsecond = firstAND & secondAND // 0b00000000
let secondANDthird = secondAND & thirdAND // 0b00000001
OR
The Bitwise OR |
operator combines the bits of two
numbers, maintaining a value of 1 for each bit that is 1 in EITHER of
the pertaining numbers.
let firstOR: UInt8 = 0b01010101
let secondOR: UInt8 = 0b10101010
let thirdOR: UInt8 = 0b00000001
let firstORsecond: UInt8 = firstOR | secondOR // 0b11111111
let secondORthird: UInt8 = secondOR | thirdOR // 0b10101011
XOR
The Bitwise XOR ^
operator (exclusive or) combines the
bits of two numbers, maintaining a value of 1 for each bit ONLY if the
value is different between each number.
let firstXOR = 0b00000011
let secondXOR = 0b00000001
let firstXORsecond = firstXOR ^ secondXOR // 0b00000010
NOT
The Bitwise NOT ~
operator ‘flips’ each bit of the input
number.
let beforeNOT: UInt8 = 0b00000000
let afterNOT = ~beforeNOT // 0b11111111
Left Shift
The Bitwise Left Shift <<
operator does exactly
what the name infers - shifts all bits to the left. Using the operator
requires specification to how many spaces the numbers bits should be
shifted. A left shift essentially doubles the current integer amount. An
important tidbit (bit humor?) is that Swift does not allow an operator
to overflow by default, meaning if bits are shifted beyond integer
bounds a crash will occur.
let leftShift: UInt8 = 0b00000001
<< 1 // 0b00000010
leftShift << 2 // 0b00000100
leftShift << 3 // 0b00001000
leftShift << 8 // error leftShift
Right Shift
The Bitwise Right Shift >>
operator is just like
its left counterpart, except that the input bits are shifted to the
right. An important difference is that a right shifted number will be
capped at zero (i.e. if shifted beyond its bounds, the result will
default to 0).
let rightShift: UInt8 = 0b00010000
>> 1 // 0b00001000
rightShift >> 2 // 0b00000100
rightShift >> 3 // 0b00000010
rightShift >> 4 // 0b00000001
rightShift >> 5 // 0b00000000 rightShift
Hexadecimal Colors
While working with a designer it is not uncommon to receive a color value represented in hexadecimal rather than RGB decimal format. Rather than converting these values using one of the numerous conversion tools available, lets instead utilize what we’ve learned about bit manipulation to create our own handy UIColor extension which converts these values for us.
extension UIColor {
init(hex: UInt32) {
convenience let redComponent = CGFloat((hex & 0xFF0000) >> 16)
let greenComponent = CGFloat((hex & 0x00FF00) >> 8)
let blueComponent = CGFloat((hex & 0x0000FF))
self.init(red: redComponent/255.0, green: greenComponent/255.0, blue: blueComponent/255.0, alpha: 1.0)
}
}
Here’s a quick rundown of how it works. The hexadecimal number system uses 16 distinct symbols to represent the values 0 - 15 (0-9 and A-F respectively). Each hexadecimal digit consists of 8 bits (a byte), which allows the representation of any number from 0 - 255. Using this information, we can extract each red, green and blue value by isolating its corresponding bits.
Starting with red, we isolate the component by ANDing our hex number with the maximum possible number of bits (FF). Next we shift our value for red to the right 16 bits to make sure it resides in the 0-255 bounds. The same process is used for both green and blue, with the exception of the number of bits required in the right shift step (8 and 0 respectively). Each component is casted to a CGFloat to ensure the proper type, then used to initialize a UIColor using each respective RGB value. We can then create UIColor’s like this:
let skyBlue = UIColor(hex: 0x86CAFF)
let grassGreen = UIColor(hex: 0x87DD65)
Another worthy addition to the toolbox!