Expressions and operators · about 35 min

Arithmetic operators and precedence

Why this matters

Calculations are everywhere: totals, averages, unit conversions, positions on a screen, wrapping around a clock. Python's arithmetic looks like school math, but a few operators behave in ways that school math never covered: two kinds of division, a remainder with a sign rule, and an exponent operator that groups right to left. Getting these exactly right, and knowing how Python decides what to compute first, prevents a whole class of quiet wrong-answer bugs that no error message will warn you about.

Expressions, operators, operands

An expression is any piece of code that produces a value: 42, x, x + 1, int(input()) * 2. An operator is a symbol like + that combines operands (the values on either side) into a new value. Python evaluates an expression into a single object; a statement such as total = price * qty then does something with it.

The arithmetic operators

OperatorMeaningExampleResult
+addition7 + 29
-subtraction7 - 25
*multiplication7 * 214
/true division7 / 23.5
//floor division7 // 23
%modulo (remainder)7 % 21
**exponent (power)7 ** 249
-xnegation-7-7

True division: /

/ always returns a float, even when the division is exact:

print(10 / 2)
print(7 / 2)
print(type(10 / 2).__name__)
5.0
3.5
float

This was a deliberate change in Python 3 (Python 2's 7 / 2 gave 3). It means / behaves like math division and its result type does not depend on the operand types.

Floor division // and modulo %

a // b divides and rounds down to the nearest whole number (the "floor"). a % b is the remainder that goes with it. They are tied together by an identity that always holds:

(a // b) * b + (a % b) == a

With positive numbers this is the long division you know: 17 divided by 5 is 3 remainder 2.

print(17 // 5, 17 % 5)
print(-17 // 5, -17 % 5)
print(17 // -5, 17 % -5)
print(7.5 // 2, 7.5 % 2)
3 2
-4 3
-4 -3
3.0 1.5

With negatives, "round down" means toward negative infinity: -17 / 5 is -3.4, and the floor of -3.4 is -4. The remainder then follows from the identity: -4 * 5 + 3 = -17. In Python the result of % always has the same sign as the divisor (or is zero). That is what you want for wrap-around arithmetic:

hour = 2
print((hour - 5) % 24)    # 5 hours before 2 o'clock
21

C, Java and JavaScript truncate toward zero instead, so -17 / 5 is -3 and -17 % 5 is -2 there. If you port code between languages, this difference matters.

Common uses of %: testing divisibility (n % 2 == 0 means even), extracting the last digit (n % 10), and wrapping indexes around ((i + 1) % length).

divmod

divmod(a, b) returns both results at once as a pair, which you can unpack into two names:

minutes, seconds = divmod(200, 60)
print(minutes, seconds)
3 20

divmod(200, 60) is the tuple (3, 20); the assignment binds minutes to 3 and seconds to 20. (Tuples and unpacking get a full treatment in module 7.)

Exponent **

print(2 ** 10)
print(2 ** -2)
print(9 ** 0.5)       # square root
print(8 ** (1 / 3))   # cube root, approximately
1024
0.25
3.0
2.0

Int to a non-negative int power stays an exact int; a negative or fractional exponent gives a float. pow(base, exp, mod) with three arguments computes (base ** exp) % mod efficiently, which cryptography relies on.

Precedence: what is computed first

When an expression has several operators, precedence decides which binds more tightly. From highest to lowest, for the arithmetic operators:

PrecedenceOperatorsGrouping
highest( ... ) parentheses
**right to left
unary -x, +x
*, /, //, %left to right
lowest (of these)+, -left to right

Comparisons (<, ==, ...) and then not, and, or come below all of these; the next lesson covers them.

print(2 + 3 * 4)       # * before +
print((2 + 3) * 4)
print(2 * 3 ** 2)      # ** before *
14
20
18

Associativity decides the order among operators of equal precedence. Most group left to right:

print(100 / 10 / 5)    # (100 / 10) / 5
print(10 - 4 - 3)      # (10 - 4) - 3
2.0
3

But ** groups right to left, as in math notation, and binds more tightly than a unary minus on its left:

print(2 ** 3 ** 2)     # 2 ** (3 ** 2) = 2 ** 9
print(-2 ** 2)         # -(2 ** 2)
print((-2) ** 2)
512
-4
4

Underneath, precedence is decided entirely at compile time. The parser builds a syntax tree in which tightly binding operators are deeper, and the compiler emits bytecode that evaluates the deepest parts first. You saw this with dis in module 1: for a + b * c the * instruction comes before the +.

Note: When in doubt, add parentheses. They cost nothing at run time and make intent obvious to the reader. (a * b) + c is clearer than relying on everyone remembering the table.

A worked example

Converting a temperature, averaging, and a percentage, with deliberate parentheses:

celsius = 37
fahrenheit = celsius * 9 / 5 + 32
scores_total = 85 + 92 + 78
average = scores_total / 3
passed, total = 18, 24
percent = passed / total * 100
print(fahrenheit, average, percent)
98.6 85.0 75.0

celsius * 9 / 5 + 32 works without parentheses because * and / group left to right and + comes last. Writing (celsius * 9 / 5) + 32 would be clearer still.

Common mistakes

Recap

Going further: the full precedence table is in the Python Language Reference, section "Operator precedence". Try import ast; print(ast.dump(ast.parse("-2 ** 2", mode="eval"), indent=2)) to see how the tree groups it.

Exercises

Exercise 1 · quiz

Floor division with a negative number

What do -7 // 2 and -7 % 2 evaluate to? Type the two results separated by a space.

Answer

// rounds down (toward negative infinity), not toward zero: -7 / 2 is -3.5, and the floor of -3.5 is -4. The remainder is chosen so that (a // b) * b + a % b == a always holds: (-4) * 2 + 1 == -7, so -7 % 2 is 1. In Python the result of % always has the sign of the divisor. (C and Java truncate toward zero instead, giving -3 and -1.)

Exercise 2 · quiz

Exponent surprises

Select all statements that are true.

Answer
  • 2 ** 3 ** 2 is 512

  • -2 ** 2 is -4

  • 2 ** -1 is 0.5

** is right-associative: 2 ** 3 ** 2 means 2 ** (3 ** 2) = 2 9 = 512. `also binds more tightly than the unary minus on its left, so-2 2means-(2 2)= -4; write(-2) 2for 4./always returns a float, so10 / 5is2.0. A negative exponent gives a float:2 -1` is 0.5.

Exercise 3 · write code

Seconds to hours, minutes, seconds

Read a whole number of seconds (0 or more). Use divmod (twice) to split it into hours, minutes and seconds, and print exactly (for input 3725):

3725 s = 1 h 2 min 5 s

divmod(a, b) returns the pair (a // b, a % b); you can unpack it into two names: q, r = divmod(a, b).

File: main.py

Starting point

total = int(input())

Example

input

3725

expected output

3725 s = 1 h 2 min 5 s

Example

input

0

expected output

0 s = 0 h 0 min 0 s
Hint 1

First split into whole minutes and leftover seconds: divmod(total, 60).

Hint 2

Then split the minutes into hours and leftover minutes: divmod(minutes, 60).

Reference solution
total = int(input())
minutes, seconds = divmod(total, 60)
hours, minutes = divmod(minutes, 60)
print(total, "s =", hours, "h", minutes, "min", seconds, "s")

Exercise 4 · write code

Precedence in a real formula

Read three whole numbers a, b, c (one per line, a is never 0, and the equation always has real roots). Print the two roots of a*x**2 + b*x + c = 0 given by the quadratic formula:

x1 = (-b + sqrt(b**2 - 4*a*c)) / (2*a)
x2 = (-b - sqrt(b**2 - 4*a*c)) / (2*a)

Compute the square root as d ** 0.5. Print exactly (for 1, -5, 6):

x1 = 3.0
x2 = 2.0

The starter has precedence bugs. Fix them with parentheses.

File: main.py

Starting point

a = int(input())
b = int(input())
c = int(input())
d = b ** 2 - 4 * a * c
x1 = -b + d ** 0.5 / 2 * a
x2 = -b - d ** 0.5 / 2 * a
print("x1 =", x1)
print("x2 =", x2)

Example

input

1
-5
6

expected output

x1 = 3.0
x2 = 2.0

Example

input

2
-4
-6

expected output

x1 = 3.0
x2 = -1.0
Hint 1

/ 2 * a means (... / 2) * a, not division by 2 * a: * and / have the same precedence and group left to right.

Hint 2

The whole numerator must be in parentheses too: (-b + d ** 0.5).

Reference solution
a = int(input())
b = int(input())
c = int(input())
d = b ** 2 - 4 * a * c
x1 = (-b + d ** 0.5) / (2 * a)
x2 = (-b - d ** 0.5) / (2 * a)
print("x1 =", x1)
print("x2 =", x2)