Published Oct 11, 2022
Contribute to Docs

Advanced operators in Swift provide the programmer with increased functionality and complex value manipulation. They build upon the basic operators and include compound assignments, bitwise, and custom operators.

## Compound Assignment Operator

Compound assignment operators combine the assignment operator `=` with another separate operation. The following operations are allowed:

• Addition, `+`
• Subtraction, `-`
• Division, `/`
• Multiplication, `*`
• Modulo, `%`

For example:

```var a = 1a +=  9 // a = 10a *= 4 // a = 40a -= 7 // a = 33a /= 3 // a = 11a %= 5 // a = 1
```

## Bitwise Operators

Bitwise operators are used to manipulate the raw data bits of a structure such as graphics, file inputs, or device drivers. While not common, these operators are very useful in their specific use cases. Swift also allows overloading of the standard operators to include a custom definition of the function.

### NOT Operator

Bitwise NOT `~` operator inverts all the bits in a number, so `0101 0101` will become `1010 1010`. It is very important to note that using the `~` operator on a signed integer, a standard integer, inverts a positive integer, n, into -(n+1) and not the inverse binary.

```var newBinaryNumber: UInt8 = 0b01010101  // 01010101var NewinvertedBinary = ~newBinaryNumber // 10101010
print(NewinvertedBinary)// Output: 170
var standardInt = 85var invertedStandardInt = ~standardInt
print(invertedStandardInt)// Output: -86
```

### AND Operator

Bitwise AND `&` operator returns a new binary from the combination of two other binary numbers. If there is a `1` in the same place in each binary string, the result will have a `1` in that digit, else, a `0` will be place

```        0 0 1 1 0 1 0 1AND     0 1 1 1 1 1 0 1EQUALS  0 0 1 1 0 1 0 1
let firstBinary = 0b00110101let secondBinary = 0b01111101let result = firstBinary & secondBinary // 00110101
```

### OR Operator

Bitwise OR `|` operator compares two numbers and returns a new number where each bit is set to `1` if either bit equals `1` in the original two numbers.

```        0 0 1 1 0 1 0 1OR      0 1 1 1 1 1 0 1EQUALS  0 1 1 1 1 1 0 1
let firstBinary = 0b00110101let secondBinary = 0b01111101let result = firstBinary | secondBinary // 01111101
```

### XOR Operator

Bitwise XOR `^` operator, also known as ‘exclusive OR’, compares two binary numbers. It will return a new number with each bit set to `1` if the bits of the original numbers are different, or exclusive. `0`s will be placed anywhere that the two bits are equivalent.

```        0 0 1 1 0 1 0 1XOR     0 1 1 1 1 1 0 1EQUALS  0 1 0 0 1 0 0 0
let firstBinary = 0b00110101let secondBinary = 0b01111101let result = firstBinary ^ secondBinary // 01001000
```

### Left and Right Shift Operators

Bitwise shift operators, `<<` and `>>` operate slightly differently on signed and unsigned values. For unsigned values, the process is very straight-forward, the number shifts to the left or right by the number of digits specified. In essence, for every shift to the left that is made, the value of the number is doubled, and for every shift right the number is halved.

```var shifty: UInt8 = 0b00001000shifty << 1        // 00010000shifty << 3        // 01000000shifty >> 7        // 00000000
// Digits shifted outside the scope of the value are discarded, as with the shift of 7 above
```

In signed numbers, the first digit represents the sign, `0` for positive, `1` for negative. For this reason, it is important to keep that digit as we shift in either direction. Let’s start with an 8-bit signed number, 15. We said the first digit was the sign, 15 is positive so the sign is `0` and the remaining 7 bits are: `0001111`. Together our 8-bit number is `00001111`. When shifted left, the signed digit remains the same and digits are “pushed” out of the binary number at the signed digit. When shifting right, instead of filling the void space with a `0`, it is filled with the signed digit.

```var signedFifteen = 0b00001111         // 0 0001111
var shiftedRight = signedFifteen >> 1  // 0 0000111// Signed digit is '0' and is used to fill  ^var shiftedLeft = signedFifteen << 4   // 0 1110000// Signed digit acts as end point, leading '1' is dropped
```

Swift also allows for custom operators to be created or existing operators to be overloaded within a given class or structure. The following examples feature a small `Student` structure that uses these operators:

```struct Student {  var name: String  var studentId: Int  var gpa: Double}
var tim = Student(name: "Tim", studentId: 234234, gpa: 2.95)var amy = Student(name: "Amy", studentId: 233241, gpa: 3.70)
```

The equatable operator (`==`) and its inverse (`!=`) will use Swift’s standard definition unless it is redefined. The “equatability” of the two students can be tested by adding conformance to `Equatable` and creating a `==` function.

```extension Student: Equatable {  static func == (student1: Student, student2: Student) -> Bool {    return student1.studentId == student2.studentId  }}
if tim == amy {  print("These students are the same")} else {  print("These are different students")}// Output: "These are different students"
```

The `==` operator is used to logically compare `studentId` properties of two students.

Swift also allows us to override most of the common operators. A complete list of them can be found in the Swift Reference Manual.

In the examples below, when “adding” or “subtracting” from a student, the goal is to manipulate the `gpa` property.

```extension Student {  static func + (left: Student, right: Double) -> Double {    if left.gpa + right > 4.0 {      return 4.0    }    return left.gpa + right  }  static func - (left: Student, right: Double) -> Double {    if left.gpa - right < 0.0 {      return 0.0    }    return left.gpa - right  }}
```

The addition `+` and subtraction `-` operators are redefined to adjust a student’s `gpa` property. Additionally, there is logic in place to prevent the `gpa` from going above `4.0` or below `0.0`.

Similar to basic operators, compound operators like `+=` can be redefined:

```extension Student {  static func += (left: inout Student, right: Double) -> Student {    left.gpa = left + right    return left  }}
```

The above examples are not inclusive of all the tasks that can be reassigned, and custom operators such as `+++` or `-+-` can also be created for example.