Numbers: division, floats and rounding
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 visibleDecimal(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.
Your task
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.
- full_tins is 4, using // (not done yet)
- left_over is 9, using % (not done yet)
- total is exactly 0.60, with Decimal (not done yet)
- Print the three values (not done yet)
The checklist ticks itself off as you work in the editor: any way that gets the result counts.
Hints come one at a time, then one way to do it. Try each before the next.
What this lesson uses, in one place.
/- Division, always giving a float: 7 / 2 is 3.5 Python docs →
//- Floor division: divides and rounds down, 7 // 2 is 3 and -7 // 2 is -4 Python docs →
%- The remainder after floor division: 7 % 2 is 1 Python docs →
**- A power: 2 ** 10 is 1024 Python docs →
0.1 + 0.2- Gives 0.30000000000000004: floats are binary fractions, so compare them with math.isclose() Python docs →
round()- Rounds to a number of decimal places; halves go to the even number, so round(2.5) is 2 Python docs →
Decimal- Exact decimal numbers for money: from decimal import Decimal, then Decimal("0.10") Python docs →