# Swift Overflow Operators (&+, &-, &*) Explained Clearly

Source: https://devdocs10.com/articles/swift/swift-overflow-operators  
By Murat Bo · Published 2026-05-01 · DevDocs10 (https://devdocs10.com)

Swift’s overflow operators let integer arithmetic continue past a type’s normal limits instead of stopping with a runtime trap. In this article, you will learn what `&+`, `&-`, and `&*` do, why Swift provides them, how wraparound arithmetic works, and when these operators are useful in real code.

## 1. What Is Overflow Operators (&+, &-, &*)?

Overflow operators are special arithmetic operators for integer types in Swift. They behave like normal addition, subtraction, and multiplication, except they allow values to wrap around when the result goes beyond the representable range of the type.

For example, a `UInt8` value can store numbers from `0` to `255`. If you add `1` to `255` using normal `+`, Swift traps at runtime. If you use `&+`, the result wraps back to `0`.

- `&+` performs overflow addition.
- `&-` performs overflow subtraction.
- `&*` performs overflow multiplication.
- They work with Swift integer types such as `Int`, `UInt`, `Int8`, and `UInt64`.
- They do not prevent overflow; they intentionally allow wraparound behavior.
- They are most useful when wraparound arithmetic is the desired result.

## 2. Why Overflow Operators Matters

Normal arithmetic in Swift is designed to be safe. If a calculation goes beyond what a type can represent, Swift stops the program rather than silently producing a wrong value. That is usually the correct choice.

However, some algorithms need arithmetic that wraps around at the type boundary. This is common in low-level programming, bit manipulation, checksums, hashing, random number generation, counters, and code that mirrors hardware or protocol behavior.

You should use overflow operators when wraparound is intentional and expected. You should not use them as a shortcut to avoid handling number range problems in ordinary business logic.

**Warning:** Overflow operators are not a safer version of normal arithmetic. They are a deliberate choice to get wraparound results.

## 3. Basic Syntax

### Using the operators

The syntax looks almost the same as normal arithmetic, but each operator starts with `&`. The following example shows all three operators with fixed-width integer types so the wraparound is easy to see.

```swift
let maxValue: UInt8 = 255
let wrappedAdd = maxValue &+ 1

let minValue: UInt8 = 0
let wrappedSubtract = minValue &- 1

let product: UInt8 = 200
let wrappedMultiply = product &* 2
```

In this code, `wrappedAdd` becomes `0`, `wrappedSubtract` becomes `255`, and `wrappedMultiply` wraps to the low 8 bits of the mathematical result.

### Why wraparound happens

Swift integer types have fixed storage sizes. A `UInt8` stores exactly 8 bits. Once a calculation goes beyond those 8 bits, overflow operators keep only the bits that fit. That is why the result appears to cycle through the valid range.

This behavior is sometimes called modular arithmetic. For `UInt8`, values wrap modulo `256`.

### Normal arithmetic versus overflow arithmetic

The next example shows the conceptual difference between the standard operators and overflow operators.

```swift
let value: UInt8 = 255

// value + 1 would trap at runtime
let wrapped = value &+ 1
```

The important idea is simple: use normal operators when overflow should be treated as a bug, and use overflow operators when wraparound is the intended outcome.

## 4. Step-by-Step Examples

### Example 1: Wrapping at the top of an unsigned range

This example shows a `UInt8` moving past its maximum value.

```swift
let highest: UInt8 = 255
let next = highest &+ 1

print(next)
```

Output (tested with Swift 6.4):

```text
0
```

The printed result is `0`. This is the simplest form of wraparound arithmetic.

### Example 2: Wrapping below zero with unsigned integers

Unsigned types cannot represent negative numbers. With normal subtraction, going below zero would trap. With `&-`, the result wraps to the top of the range.

```swift
let start: UInt8 = 0
let previous = start &- 1

print(previous)
```

Output (tested with Swift 6.4):

```text
255
```

The result is `255`. This is useful for cyclic counters or byte-based operations.

### Example 3: Overflow multiplication with a small integer type

Multiplication can overflow quickly with small fixed-width types. This example makes that visible.

```swift
let a: UInt8 = 200
let b: UInt8 = 2
let result = a &* b

print(result)
```

Output (tested with Swift 6.4):

```text
144
```

The mathematical result is `400`, but `UInt8` can only store up to `255`. The value wraps and the stored result is `144`.

### Example 4: Signed integer wraparound

Overflow operators also work with signed integers. Here, adding past the maximum signed value wraps to the minimum signed value.

```swift
let largest: Int8 = 127
let wrapped = largest &+ 1

print(wrapped)
```

Output (tested with Swift 6.4):

```text
-128
```

The result is `-128`. Signed integers use two’s-complement representation, so the wraparound follows that bit pattern.

## 5. Practical Use Cases

- Implementing cyclic counters that should restart automatically after reaching a maximum value.
- Working with raw bytes in binary formats, network protocols, or file parsers.
- Building hash functions or checksum logic where modular arithmetic is part of the algorithm.
- Writing pseudo-random number generators that depend on fixed-width integer wraparound.
- Mirroring low-level hardware behavior where arithmetic is naturally limited by register size.
- Performing bit-level transformations where the wrapped result is expected and meaningful.

## 6. Common Mistakes

### Mistake 1: Using overflow operators when normal arithmetic is actually needed

Some developers use overflow operators just to avoid runtime traps, but that often hides a logic bug.

**Warning:** Bad pattern: wraparound used to ignore invalid numeric growth.

```swift
let cartItemCount: UInt8 = 255
let newCount = cartItemCount &+ 1
```

This wraps to `0`, which is clearly wrong for a shopping cart count.

Use a larger type or validate the operation instead.

```swift
let cartItemCount: Int = 255
let newCount = cartItemCount + 1
```

The corrected version uses a more appropriate type and standard arithmetic.

### Mistake 2: Expecting overflow operators to work with floating-point values

Overflow operators are for integer arithmetic, not floating-point types like `Double` or `Float`.

**Warning:** Bad pattern: using overflow operators with non-integer types.

```swift
// This does not compile
let value: Double = 10.5
// let result = value &+ 1.0
```

Use normal floating-point arithmetic instead.

```swift
let value: Double = 10.5
let result = value + 1.0
```

The corrected code uses the standard operator because floating-point types follow different numeric rules.

### Mistake 3: Forgetting that type size changes the result

The same arithmetic can produce different wrapped results depending on whether you use `UInt8`, `UInt16`, or `UInt32`.

**Warning:** Bad pattern: assuming all integer types wrap the same way.

```swift
let small: UInt8 = 250
let wrapped = small &+ 10
```

This wraps because `UInt8` has a small range.

```swift
let larger: UInt16 = 250
let result = larger &+ 10
```

Here the result is simply `260` because `UInt16` has room for that value.

## 7. Best Practices

### Practice 1: Use overflow operators only when wraparound is part of the design

Make your intent explicit. If the algorithm depends on modular arithmetic, overflow operators communicate that clearly to readers.

```swift
var byte: UInt8 = 255
byte = byte &+ 1
```

This is appropriate because wrapping from `255` to `0` is intentional.

### Practice 2: Prefer fixed-width integer types when exact overflow behavior matters

If you rely on exact bit width, use types like `UInt8`, `UInt32`, or `Int16` instead of platform-sized types when consistency is important.

```swift
let seed: UInt32 = 4_294_967_295
let nextSeed = seed &+ 1
```

This always wraps the same way because `UInt32` has a known width.

### Practice 3: Add comments when the wraparound may not be obvious

Overflow arithmetic can surprise readers who expect normal safety checks. A short comment helps explain why it is correct here.

```swift
let checksum: UInt8 = 250
// Wraparound is intentional because the protocol uses byte-sized modular arithmetic.
let updatedChecksum = checksum &+ 10
```

The code is clearer because the reason for using `&+` is documented.

## 8. Limitations and Edge Cases

- Overflow operators apply to integer types, not floating-point numbers.
- The wrapped result depends on the type’s bit width. A calculation on `UInt8` may wrap while the same one on `UInt64` may not.
- `Int` and `UInt` are platform-sized types, so their exact range depends on the target architecture.
- Signed wraparound can be harder to reason about than unsigned wraparound because negative values are represented using two’s complement.
- Overflow operators do not report whether overflow happened. They only give the wrapped result.
- If you need both the result and an overflow flag, methods such as `addingReportingOverflow(_:)`, `subtractingReportingOverflow(_:)`, and `multipliedReportingOverflow(by:)` may be a better fit.

> Overflow operators are useful, but if you need to detect overflow instead of silently wrapping, the reporting APIs are often the better tool.

## 9. Practical Mini Project

Let’s build a tiny byte counter that simulates a one-byte device register. A one-byte register can store values from `0` to `255`. Incrementing past the maximum should wrap back to `0`.

```swift
struct ByteCounter {
    private(set) var value: UInt8 = 0

    mutating func increment() {
        value = value &+ 1
    }

    mutating func decrement() {
        value = value &- 1
    }
}

var counter = ByteCounter()

for _ in 1...3 {
    counter.decrement()
    print(counter.value)
}

counter = ByteCounter()
for _ in 1...257 {
    counter.increment()
}

print(counter.value)
```

Output (tested with Swift 6.4):

```text
255
254
253
1
```

This small project demonstrates both directions of wraparound. Starting from `0`, decrementing three times produces `255`, `254`, and `253`. Then incrementing 257 times wraps once and ends at `1`.

The example is simple, but it models real situations where storage size is fixed and cyclic arithmetic is expected.

## 10. Key Points

- `&+`, `&-`, and `&*` are Swift’s integer overflow operators.
- They allow arithmetic to wrap around instead of trapping at runtime.
- They are useful when modular arithmetic is intentional, such as byte processing or low-level algorithms.
- The wrapped result depends on the specific integer type and its bit width.
- They should not be used to hide ordinary numeric bugs in application logic.
- If you need to know whether overflow occurred, use the reporting overflow methods instead.

## 11. Practice Exercise

Build a small program that simulates a one-byte score value.

- Create a `UInt8` variable named `score` starting at `254`.
- Add `3` using an overflow operator.
- Subtract `5` using an overflow operator.
- Print the intermediate and final results.

**Expected output:** the value should wrap during addition and still produce a valid `UInt8` result after subtraction.

**Hint:** Start with `254`, then apply `&+ 3`, then `&- 5`.

```swift
var score: UInt8 = 254

score = score &+ 3
print("After adding 3: \(score)")

score = score &- 5
print("After subtracting 5: \(score)")
```

Output (tested with Swift 6.4):

```text
After adding 3: 1
After subtracting 5: 252
```

This solution first wraps `254` forward by three steps, giving `1`. It then subtracts five with wraparound, producing `252`.

## 12. Final Summary

Swift overflow operators give you explicit control over wraparound arithmetic for integers. Instead of trapping when a value goes beyond the range of its type, `&+`, `&-`, and `&*` keep the calculation within the type’s fixed bit width and return the wrapped result.

That behavior is powerful when it matches the problem you are solving, especially in byte manipulation, hashing, cyclic counters, and low-level data processing. It is not a replacement for normal arithmetic safety, though. In most app code, standard operators are still the better choice because they expose range errors instead of hiding them.

A good next step is to learn Swift’s overflow-reporting methods so you can compare intentional wraparound with arithmetic that also tells you whether an overflow occurred.
