Arithmetic and integer division
What you'll learn:
- predict the result of integer division and remainder, negative numbers included;
- pick an integer type's size and notice the overflow Go keeps quiet about;
- compare values and combine conditions with
&&,||and!; - compare fractional numbers with a tolerance instead of
==.

Go counts like a calculator, but this calculator has rules of its own. It remembers the type of every number: whole or fractional.
The operators +, - and * work on whole numbers the same way school arithmetic does. Division is different: when both numbers have type int, the result is an int too, and an int has no fractional part.
Picture sharing apples among kids. You can't cut the apples, so each kid gets a whole number of them, and the extras stay with you. That is how dividing whole numbers works:
package main
import "fmt"
func main() {
apples := 17
kids := 5
fmt.Println(apples / kids) // 3
fmt.Println(apples % kids) // 2
}Let's see what the program printed:
apples / kidsprints3: seventeen apples shared among five kids give three each. The/operator produced the quotient.apples % kidsprints2: two apples stay with you. The%operator produced the remainder.
An ordinary calculator would show 3.4, but Go showed 3. The apple picture works well for positive numbers, while negative ones follow a rule of their own, covered in the section on the remainder.
A quotient without a fraction
The values an operator works on are called operands. Dividing two integer operands is integer division: the fractional part of the result is discarded, not rounded.
17 / 5is3, even though on paper it comes to3.4.19 / 5is also3, even though3.8is closer to four.-17 / 5is-3, not-4: a negative result drops its fraction too.
So integer division always moves the result toward zero: a positive one down, a negative one up.
Getting a fraction
A fraction comes from dividing numbers of type float64. A number written directly in the code is a literal. Here are two ways to get a fractional result:
a, b := 17, 5
fmt.Println(7.0 / 2) // 3.5
fmt.Println(float64(a) / float64(b)) // 3.4A fractional literal: 7.0 / 2
A literal with a dot, such as 7.0, is already fractional. The literal 2 next to it adapts to the fractional type, and the result is 3.5.
This way fits numbers written directly in the code. It does not work with variables: a variable already has its type and cannot adapt.
Converting variables: float64(a) / float64(b)
The expression float64(a) takes the value of the integer variable a and turns it into a fractional one. The variable a itself stays an int.
- Convert both variables: then both operands are
float64, and the result is3.4. - Converting only one does not compile: in
float64(a) / bthe operand types differ.
Division by zero
What happens when you divide an integer by zero depends on when the zero becomes known.
Zero known at build time
Dividing by the literal 0 does not compile: invalid operation: division by zero. Dividing by a constant equal to zero, such as z after const z = 0, gives the same message.
The compiler sees that value in advance, so the error is caught before the program runs.
Zero in a variable
If an integer variable turns out to be zero, the compiler does not know it. The program starts and runs the lines before the division. At the division itself, it stops with the message panic: runtime error: integer divide by zero.
Such a crash is called a panic. Before dividing by a variable that may be zero, check it.
Remainder
The % operator follows three rules:
- it works only on integer operands;
- it ranks with
*and/, left to right; - it is linked to the quotient:
a / b * b + a % bequalsa.
The third rule means the remainder takes the sign of the dividend, the left operand:
fmt.Println(-17/5, -17%5) // -3 -2
fmt.Println(17/-5, 17%-5) // -3 2Let's check both lines:
fmt.Println(-17/5, -17%5)prints-3 -2. The quotient is-3, and-3 * 5is-15. To reach-17,-2is missing, and that is the remainder.fmt.Println(17/-5, 17%-5)prints-3 2. The dividend17is positive, so the remainder2is positive too, even though the divisor is negative.
Interviewers like to ask this: what sign does the remainder have when the dividend is negative? In math the remainder is usually taken as non-negative, while in Go it takes the sign of the dividend.
Digits of a number
The remainder helps take a number apart into digits. For 253:
n % 10is the last digit,3;n / 10is the number without it,25.
Common mistake
The result of dividing two int values is converted to float64 in the hope of getting a fraction:
package main
import "fmt"
func main() {
total := 5
count := 2
half := float64(total / count) // ✗
fmt.Println(half) // 2
}The compiler sees no error, and the program prints 2. First total / count runs as integer division, and only its result 2 becomes a float64. Convert the operands, not the result: float64(total) / float64(count) gives 2.5.
Key points
- Dividing two integers drops the fraction:
17 / 5is3, and-17 / 5is-3. - The
%operator gives the remainder, and its sign matches the dividend's. - To get a fraction, convert the operands to
float64, not the result. - Dividing by the literal
0does not compile; dividing by an integer variable equal to zero panics.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.