• Swift provides a several advanced operators bitwise and bit shifting to perform a more complex operations.
  • In swift, Arithmetic operators won’t show the overflow value by default.
  • To opt the behavior of overflow, swift uses the second set of advanced operators such as the addition operators +& and all these operators are beginning with &.

1. Swift Bitwise Operators

  • In swift, Bitwise operators enable us to work with raw data bits to perform bit by bit operation on data structure.

1.1 Swift Bitwise NOT Operator

  • Bitwise NOT Operator ~ will invert all bits in input number like if we have positive bit **1 it inverts into negative 0 and vice versa.
let intialBits : UInt8 = 0b11110000
let invertBits = ~intialBits  
print("Initial bits are:",intialBits)
print("Invert bits after applying ~ operator are:",invertBits)
/*results
Initial bits are: 240
Invert bits after applying ~ operator are: 15 */ 

1.2 Swift Bitwise AND Operator

  • Bitwise AND operator & is used to compare the bits of two input numbers. The Bitwise AND operator will return result as 1 only when both input bits are equals to 1 otherwise it will return 0.
let inputA : UInt8 = 0b00000110
let inputB : UInt8 = 0b00000101
let result = inputA & inputB 
print("Result after applying & operator:",result)
/* result
Result after applying & operator: 4*/

1.3 Swift Bitwise OR Operator

  • Bitwise OR operator | is used to compare the bits of two input numbers. The Bitwise OR operator returns 1 only when anyone of input bit is equal to 1 otherwise it will return 0.
let result2 = inputA | inputB  
print("Result after applying | operator:",result2)
/* result
Result after applying | operator: 7 */

1.4 Swift Bitwise XOR Operator

  • Bitwise XOR operator or Exclusive OR operator ^ is used to compare the bits of two numbers. The Bitwise XOR operator returns 1 only when input bits are different and it returns 0 incase input bits are same.
let result3 = inputA ^ inputB  
print("Result after applying ^ operator:",result3)
/* results 
Result after applying ^ operator: 3 */

2. Swift Bitwise Left and Right Shift Operators

  • The bitwise left shift operator << and bitwise right shift operator >> move all bits in a number to the left or the right by a certain number of places, according to the rules defined below:

Shifting Behavior for Unsigned Integers:

  1. Existing bits are moved to the left or right by the requested number of places.
  2. Any bits that are moved beyond the bounds of the integer’s storage are discarded.
  3. Zeros are inserted in the spaces left behind after the original bits are moved to the left or right.
let shiftBits: UInt8 = 4
print("After shifting bits  to left by 1:",shiftBits << 1)
print("After shifting bits to right by 1:", shiftBits >> 1)
print("After shifting bits  to left by 4:",shiftBits << 4)
print("After shifting bits to right by 4:", shiftBits >> 4)
/* prints 
After shifting bits  to left by 1: 8
After shifting bits to right by 1: 2
After shifting bits  to left by 4: 64
After shifting bits to right by 4: 0
*/

3. Swift Overflow operators

  • In swift, when we try to insert a too large or too small number into constant or variable integer that cannot hold that value, by default Swift will throw an error instead of allowing to create an invalid value. The overflow operator is helpful when we need to work with numbers that are too small or large.

  • Swift provides a three types of operators to handle errors when values gets too large or too small. By using these operators we can opt into the overflow behavior for integer calculations instead of throwing an error.

  • Following are the overflow operators available in swift programming language. All these operators will begin with ampersand (&).

    • Overflow Addition (&+)
    • Overflow Subtraction (&-)
    • Overflow Multiplication (&*)
  • In swift, numbers can overflow either in negative or positive direction. Following is the example of overflow an integer value in positive direction using an overflow addition operator (&+) to handle overflow exceptions.

3.1 Overflow Addition &+

// Uncommenting this code will show an overflow error:
// var num = Int32.max 
// num += 1
// print(num)

//After using overflow addition operator:

var overflownum = UInt8.max
overflownum = overflownum &+ 1
print("After using overflow addition operator &+:",overflownum)

/* results: 
After using overflow addition operator &+: 0 */

3.2 Overflow Subtraction &-

var overflownum = UInt8.min
overflownum = overflownum &- 1
print("After using overflow subtraction operator &-: ",overflownum)

/* results:
After using overflow subtraction operator &-:  255 */

4. Swift Operators Precedence and Associativity

  • Operator Precedence means giving a high priority to some operators and these operators will apply first.
  • Operator Associativity defines how operators of the same precedence are grouped together, either grouped from the left side or right side.
var result = 34 + 2 % 6 * 3  
print(result)

//results 40
  • In swift, remainder (%) and multiplication (*) operators have a higher precedence than addition (+) operator due to that remainder and multiplication operators will evaluate first then addition operation will perform.

  • The remainder (%) and multiplication (*) operators have a same precedence in that case we need to consider the associativity of operators. Here both remainder and multiplication operators are associated with the expression to their left so the expression will start from their left like as shown below

    • Step 1: 34 + ((2 % 6) * 3) // Associativity and Precedence
    • Step 2: 34 + (2 * 3) // Precedence
    • Step 3: 34 + 6 = 40

5. Swift Operator Method

5.1 Swift Postfix and Prefix Operator Method

  • Operator methods allow us to declare the method which perform special type of task.
  • Structures and classes provide their own implementation in their existing operators. This is known as overloading of operator.
  • Following is the example to overload subtraction (-) sign and convert our positive integer into negative integer.
struct Conversion {
var number = 0.0
}
prefix func - (ConvertNum: Conversion) -> Conversion {
return Conversion(number: -ConvertNum.number)
}
let pos = Conversion(number: 5.0)
print(pos)
let neg = -pos
print(neg)

/* results:
Conversion(number: 5.0)
Conversion(number: -5.0) */ 

5.2 Swift Compound Assignment Operator

  • Computer assignment operator means it’s a combination of assignment (=) operator with another operation. For example, the addition assignment operator (+=) is a combination of addition (+) and assignment (=) into single operation.
  • Following is the example of implementing addition assignment operator in swift programming language:
struct Vector2D {
    var x = 0.0, y = 0.0
}

extension Vector2D {
    static func + (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y + right.y)
    }
}

extension Vector2D {
    static func += (left : inout Vector2D, right: Vector2D) {
        left = left + right
    }
}

let vector = Vector2D(x: 3.0, y: 1.0)
print(vector)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
print(anotherVector)
let combinedVector = vector + anotherVector
print(combinedVector)

/* prints:
Vector2D(x: 3.0, y: 1.0)
Vector2D(x: 2.0, y: 4.0)
Vector2D(x: 5.0, y: 5.0) */

5.3 Equivalence Operators

  • Custom classes and structures do not receive a default implementation of the equivalence operators, known as the equal to operator == and not equal to operator !=.
extension Vector2D {
    static func == (left: Vector2D, right: Vector2D) -> Bool {
        return (left.x == right.x) && (left.y == right.y)
    }
    static func != (left: Vector2D, right: Vector2D) -> Bool {
        return !(left == right)
    }
}

let twoThree = Vector2D(x: 2.0, y: 3.0)
let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)
if twoThree == anotherTwoThree {
    print("These two vectors are equivalent.")
}

/* prints:
These two vectors are equivalent. */

5.4 Swift Custom Operator

  • We can declare and implement our own custom operators in addition to the standard operators provided by swift.
  • We need to define a new operators in global level using operator keyword and those need to mark with prefix, infix or postfix modifiers.
prefix operator +++
extension Vector2D {
    static prefix func +++ (vector: inout Vector2D) -> Vector2D {
        vector += vector
        return vector
    }
}

var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
print(toBeDoubled)
let afterDoubling = +++toBeDoubled
print(afterDoubling)

/* prints:
Vector2D(x: 1.0, y: 4.0)
Vector2D(x: 2.0, y: 8.0)*/

You can download the swift playground of all above examples from Here