Lesson 21 of 26 · about 16 min
Floats and approximation
Computers store most decimals only approximately, so 0.1 + 0.2 isn't exactly 0.3. Instead of exact answers, good programs find answers that are close enough, fast.
🧭 What you need first: Testing and debugging , Counting with switches
Try writing 1/3 as a decimal: 0.33333… You have to stop somewhere, and wherever you stop, you’re slightly wrong. Computers have the same problem, but in binary, where even friendly-looking numbers like 0.1 go on forever. So Python stores the closest number it can, and tiny errors appear: 0.1 + 0.2 gives 0.30000000000000004.
The lesson isn’t “computers are bad at math.” It’s that “close enough” is a powerful idea. Engineers don’t need the exact square root of 2; they need it to 6 decimal places, fast.
And there’s a beautifully fast way to get close: the guessing game where every guess cuts the possibilities in half.
Another way: finding a word in a dictionary
You don’t read a paper dictionary from page 1. You open it in the middle: “mango” is after “lemon,” so you only look in the back half. Then the middle of that half. A few flips and you’re there. That’s bisection.
Another way: tuning a shower
Too hot? Turn it halfway toward cold. Too cold now? Halfway back. Each adjustment is smaller than the last, and in a few tries it’s just right.
Halve your way to √25
Press Try the middle repeatedly. Watch the blue range shrink by half each time. Then pick √2, which never ends as a decimal, and see how quickly you get “close enough.”
The answer is somewhere between 0.0000 and 25.0000. Next guess: the middle, 12.5000
Compare: guessing 0.001, 0.002, 0.003… one by one would need about 5,000 guesses for √25.
And see floating-point error for yourself:
The real words
Floating point
- A float stores numbers in binary scientific notation (like 1.01 × 2³). It has limited room, so most decimals are stored as the nearest possible value. This is floating-point error.
- Never test floats with
==. Use a tolerance:abs(a - b) < epsilon. (math.isclose(a, b)does this for you.) - For money, store whole cents as ints (
1999instead of19.99), or use Python’sdecimalmodule.
Two ways to find an answer
- Guess-and-check (also called exhaustive enumeration): try every candidate in order. Finding √25 to 0.001 by stepping 0.001 at a time takes about 5,000 guesses.
- Bisection search: if the answer is between
lowandhigh, guessmid = (low + high) / 2. Too small? The answer is in the upper half:low = mid. Too big?high = mid. Repeat until close enough. - Each guess halves the range. After k guesses the range is 1/2ᵏ of what you started with: 10 guesses → 1/1024, 20 guesses → about 1/1,000,000. This “halving” growth is called logarithmic, and you’ll see it again and again (lesson 24, and F17).
- Bisection only works when you can tell which direction to go (too high vs too low).
Write your own square-root finder
Write sqrt(x) using bisection: start with low = 0 and high = max(1, x), and keep halving until guess * guess is within 0.0001 of x. Also count the guesses in a global num_guesses (the starter does this for you).
How many guesses?
Using bisection, about how many guesses do you need to find a number between 1 and 1,000,000?
What's the safest way to check if two floats a and b are equal?
Got it?
Finish the lesson to color it in on your map and collect its concept cards.
Did this lesson click?