Skip to content

Numbers: division, floats and rounding

BeginnerLesson 4 of 147 min

Divide with / and //, find remainders with %, see why 0.1 + 0.2 isn’t exactly 0.3 in Python, how round() really rounds, and when to use Decimal.

Python has two everyday kinds of number: int for whole numbers and float for numbers with a decimal point. The usual operators work, plus a few you may not know:

print(7 + 2, 7 - 2, 7 * 2)  # 9 5 14
print(7 / 2)                # 3.5: / always gives a float
print(7 // 2)               # 3: floor division, drops the fraction
print(7 % 2)                # 1: the remainder
print(2 ** 10)              # 1024: a power

// and % belong together: 7 // 2 is how many whole 2s fit in 7, and 7 % 2 is what's left over. // rounds down, towards minus infinity, so -7 // 2 is -4, not -3.

Python's ints have no size limit. 2 ** 200 prints all 61 digits.

Floats aren't exact

print(0.1 + 0.2)          # 0.30000000000000004
print(0.1 + 0.2 == 0.3)   # False

That isn't a Python bug. A float is stored in binary, and most decimal fractions, like 0.1, have no exact binary form, just as 1/3 has no exact decimal form (0.333…). The stored value is a tiny bit off, and sometimes the error shows. Every language that uses the standard floating-point numbers does the same.

So don't test floats with ==. Ask whether they're close instead:

import math
print(math.isclose(0.1 + 0.2, 0.3))  # True

round()

round(x, 2) rounds to 2 decimal places, and round(x) to a whole number. Halves go to the nearest even number, which keeps totals fair when you round lots of values:

print(round(2.5), round(3.5))  # 2 4
print(round(19.987, 2))        # 19.99

Decimal, for money

When every cent must add up, the decimal module counts in base 10, like you do. Give it the numbers as strings:

from decimal import Decimal
print(Decimal("0.1") + Decimal("0.2"))  # 0.3
print(Decimal(0.1))                     # the float's error, made visible

Decimal(0.1) starts from the float, error and all, which is why the strings matter.

More in the Python docs: floating-point arithmetic: issues and limitations, round() and decimal.

Your turn

57 biscuits go into tins of 12. Make full_tins the number of full tins with // and left_over the biscuits left with %. Then make total the exact sum of 0.10, 0.20 and 0.30 using Decimal, and print full_tins, left_over and total.

Next →