Bonus lessons are optional.
Try this in the console:
- 0.1 * 3
What do you expect? What did you get?

Georgina
Huh? It should be 0.3, but I got 0.30000000000000004!
Right.
It happens because of the way compies do math. We humans use base 10, where we have ten digits, 0 through 9. When we get to 9 and add 1, we add another place to the left: 10. Get to 99, add 1, we get 100. Another place to the left.
Compies aren't like us. They use binary, or base 2. We have 10 digits, compies only have two: 0 and 1. They count like this: 1, 10, 11, 100, 101, 110, 111, 1000... Each place contains a binary digit, or bit.

Ray
You'd need lotsa bits for a large number, like 3,223,399.
Indeed! In binary, that's 1100010010111101100111.
I used the bin() function to work that out.
When you give Python an expression in decimal, like 0.1 * 3
, Python converts each piece into binary, does the calculation in binary, and converts the result back into decimal.
Trouble is, those conversions can give you round-off error, since calculations that are round in decimal might not be round in binary, and vice versa.
Usually, this isn't a problem. The error in 0.30000000000000004 is..., well, very small. Quadrillionthish small. Apply the round
function to it, and the error will go away.

Adela
You have but-face. You're about to say but.
Aye. But try this in the console.
- 0.1 * 3 == 0.3
Wadja get?

Ethan
False. That's not good.
Aye, not good.
Check out this code.
- num = 0.0
- while num != 0.3:
- user_input = float(input('What number when multiplied by 3 will give you 0.3? '))
- num = user_input * 3.0
- if num != 0.3:
- print("That's not it. Please try again.")
- print('OK, bye!')
Run the program. What happened? Why?

Georgina
Well, that's a pain. The program loops forever. I had to Ctrl+C
to stop it.
I put in 0.1 for the input. Line 4 multiples that by 3. We should get 0.3, but the debugger says we actually get 0.30000000000000004.
The while
in line 2 compares 0.30000000000000004 to 0.3. They aren't the same, so the loop keeps going.
Aye! And you're right, it is a pain.
It won't be a big problem for the rest of this course, since we'll use loops that aren't affected by the issue. But you might come across it later if you do more with Python.
There are a coupla solutions. An easy one is in Python's math
library, the function isclose
. It returns True
if two floats are nearly equal, False
if they aren't. It only allows a tiny difference.
Try this.
- import math
- num = 0.0
- while not math.isclose(num, 0.3):
- user_input = float(input('What number when multiplied by 3 will give you 0.3? '))
- num = user_input * 3.0
- if not math.isclose(num, 0.3):
- print("That's not it. Please try again.")
- print('OK, bye!')
isclose
is in the math
library, so you need to import that first. You can see the new tests in lines 4 and 7.
Try it. What happened?

Ray
It worked!
Yay!
Bee tee dubs, this is a problem in every language I've worked with.
Summary
- Round-off error happens because calculations that are round in decimal might not be round in binary.
- Usually it isn't an issue because the differences are tiny, but sometimes it causes problems.
isclose
in themath
library returns true if two floats are nearly equal.