Skip to content
Theory · Operators · lesson 3 of 7

Overflow

In the previous lesson Swift's calculator shared out sweets. It has another rule too: every integer type has a limit.

Picture a counter with three wheels of digits. It shows numbers from 000 to 999. An ordinary counter, like the mileage in an old car, would roll over from 999 to 000 and show a wrong number without warning anyone. Swift's counter is stricter: it refuses to roll over and stops the work.

The wheel picture is wrong in one way: a computer has no decimal wheels. A number is stored in binary digits, bits, so the limits of types are not 999 but numbers like 127.

Why think about it? In 2014 the view count of the Gangnam Style video on YouTube passed 2147483647. That is the limit of a 32-bit whole number, and YouTube moved its view counter to 64-bit numbers.

The limits of integer types

On computers and phones the Int type takes 64 bits. The smallest and the largest Int values are stored in Int.min and Int.max:

SWIFT
print(Int.min) // -9223372036854775808
print(Int.max) // 9223372036854775807
print(Int8.min, Int8.max) // -128 127

What the program printed:

  1. Int.min and Int.max are the limits of Int, about nine quintillion either way.
  2. Int8 takes only 8 bits, and it holds numbers from -128 to 127.

Besides Int and Int8, there are Int16, Int32 and Int64: the number in the name tells how many bits the type takes. Ordinary programs almost always use Int. Small types show up where every bit of memory counts, for example in files. In this lesson Int8 is handy because its edge is close.

Different integer types don't mix: you can't add an Int to an Int8. A number of another type is converted first, for example Int8(bonus). A number written right in the code, such as 10, takes the type it needs on its own, so it is added to an Int8 without converting.

When the result does not fit

When the result of an operation does not fit its type, it is called an overflow. The plain +, - and * never go over the edge silently. What exactly happens depends on when Swift notices the overflow.

The compiler sees the overflow

SWIFT
var level: Int8 = 120
level += 10 // ✗
TEXT
error: arithmetic operation '120 + 10' (on type 'Int8') results in an overflow

The compiler worked out 120 + 10 itself, got 130 and refused to build the program. As with any compile error, the program does not start at all.

The program notices the overflow while running

SWIFT
let bonus = 10
var health: Int8 = 120
health += Int8(bonus) // ✗
print(health)

Here bonus has type Int, so it is converted to Int8. The compiler did not work out the sum of health and Int8(bonus) in advance, and the check fired at run time:

  1. The sum 130 did not fit in Int8.
  2. The program crashed on the line with +=: it stopped in the middle of its work.
  3. print(health) never ran.

Many crashes print a Fatal error: line with the reason, but an overflow does not. The terminal shows only a crash report with the words Illegal instruction (on Linux). Xcode shows the reason: it stops on this line with Swift runtime failure: arithmetic overflow.

Which overflows the compiler finds in advance depends on what it managed to work out itself. Don't rely on it: in real programs numbers arrive while the program runs, typed by a user or sent by a server. One thing is certain: the plain + never goes over the edge, it stops the program.

Interviewers often ask this: what happens when an Int overflows in Swift? A good answer: the program crashes, and going over the edge is written explicitly, with special operators.

Going over the edge on purpose

Sometimes a counter that rolls over is exactly what you want: after 127 comes -128. For this Swift has the overflow operators &+, &- and &*. They count like +, - and *, but a result that does not fit is carried over to the other edge of the type.

Press "Next step" and watch counter: on the second addition a plain + would stop the program, while &+ carries the count over to -128.

Live&+ goes over the edgestep 1 of 9 · frames: 1

counter has type Int8: it holds numbers from -128 to 127.

Watch counter: on the second addition a plain + would stop the program

What the widget showed:

  • 126 &+ 1 gives 127: the result fits, and &+ works like +.
  • 127 &+ 1 gives -128: after the largest Int8 comes the smallest.
  • -127 &- 2 gives 127: past the bottom edge the count goes to the top.

You rarely need these operators, for example in checksums—numbers used to check that a file is not damaged. Carrying over the edge is part of their calculation.

Common mistake

The program crashed on an overflow, and + was replaced with &+ to make the crash go away:

SWIFT
var score: Int8 = 120
score = score &+ 10 // ✗
print(score) // -126

The crash is gone, but the score turned negative: -126 instead of 130. The program carries on with a wrong number and warns no one. If a number can grow, choose a type it fits in. Usually that is Int.

Key points

  • Every integer type has a limit: Int8 holds numbers from -128 to 127, and Int goes up to Int.max.
  • An overflow the compiler worked out itself gives a compile error.
  • An overflow at run time crashes the program on the line where it happened, with no Fatal error message.
  • &+, &- and &* go over the edge on purpose, and they are not a fix for an overflow.