Studio 5 โ€” Approximation Methods & Floating-Point

ENGR 103 โ€” Week 5

๐Ÿ“‹ Contents

Studio Overview0:00โ€“0:10 โ€” Warm-Up0:10โ€“0:35 โ€” Part 1 โ€” Codedex Warmup (Guided)0:35โ€“1:10 โ€” Part 2 โ€” Practical Lab: Parabola Root Search1:10โ€“1:25 โ€” Part 3 โ€” Extension: Cube Root Search1:25โ€“1:30 โ€” Wrap-Up & TA Check-Off

Student Instructions | Week 5 | Topics: Exhaustive approximation, epsilon, float precision

Oregon State University | ENGR 103 | Dr. Cheng Li

Studio Overview

0:00โ€“0:10 โ€” Warm-Up

Predict and then verify:

Float Surprise

Type and run this code:

x = 0.1 + 0.1 + 0.1
print(x)
print(x == 0.3)
print(abs(x - 0.3) < 1e-10)
โœ๏ธ Your Task:

Why does x == 0.3 return False? How does the third line fix it?

0:10โ€“0:35 โ€” Part 1 โ€” Codedex Warmup (Guided)

Type and run each snippet.

Exercise 5A โ€” Exhaustive Approximation of โˆšx

Type and run this code:

x   = 2.0
eps = 0.01       # acceptable error
step = eps ** 2  # step must be << eps
ans  = 0.0
count = 0

while abs(ans**2 - x) >= eps and ans <= x:
    ans  += step
    count += 1

if abs(ans**2 - x) < eps:
    print(f'โˆš{x} โ‰ˆ {ans:.6f}  (true: {x**0.5:.6f})')
    print(f'Steps taken: {count:,}')
    print(f'Error: {abs(ans - x**0.5):.6f}')
else:
    print('Failed to find answer')
โœ๏ธ Your Task:

Try x=9.0, eps=0.001. How many steps? How does step count change?

Exercise 5B โ€” Quadratic Root Search

We want to find x where xยฒ โˆ’ 5x = target using exhaustive search, then compare to the analytical formula. Type and run this code:

# Find x where x^2 - 5x = target by exhaustive search
target    = 6.0
eps       = 0.005

x         = 0.0
best_x    = x
best_diff = abs(x**2 - 5*x - target)

while x <= 20.0:
    diff = abs(x**2 - 5*x - target)
    if diff < best_diff:
        best_diff = diff
        best_x    = x
    x += 0.001

# Analytical positive root: x = (5 + sqrt(25 + 4*target)) / 2
x_exact = (5 + (25 + 4*target)**0.5) / 2
print(f'Numerical  x = {best_x:.4f}')
print(f'Analytical x = {x_exact:.4f}')
print(f'Error: {abs(best_x - x_exact):.5f}')
โœ๏ธ Your Task:

Try target = 14. Does the numerical answer still match the analytical one?

Exercise 5C โ€” Float Precision Demo

Type and run this code:

print('=== Float Precision ===')
for base in [0.1, 0.2, 0.3]:
    print(f'{base} ร— 10 = {base * 10:.20f}')

# Approximations of ฯ€ and tolerance check
approx_pi = [3.142, 3.139, 3.141, 3.145, 3.137]
true_pi   = 3.14159
eps_pi    = 0.003

print('\n=== Pi Approximation Check ===')
for val in approx_pi:
    ok = abs(val - true_pi) <= eps_pi
    print(f'ฯ€โ‰ˆ{val:.3f}  diff={abs(val - true_pi):.5f}  {"PASS" if ok else "FAIL"}')
โœ๏ธ Your Task:

Change eps_pi to 0.001. Which approximations fail now?

0:35โ€“1:10 โ€” Part 2 โ€” Practical Lab: Parabola Root Search

Work in pairs. The parabola y = xยฒ โˆ’ 6x + 5 has roots at x = 1 and x = 5, and a minimum of y = โˆ’4 at x = 3. Use exhaustive approximation to find x where y equals a given target value. No functions needed โ€” compute y directly inside your loops.

Setup

Type and run this code to verify the parabola at key points:

# Parabola: y = x^2 - 6x + 5
# Verify known points: roots at x=1 and x=5, minimum at x=3
for x_check in [1, 3, 5]:
    y_check = x_check**2 - 6*x_check + 5
    print(f'x = {x_check}  โ†’  y = {y_check:.3f}')
โœ๏ธ Your Task:

Run the verification. Do x=1 and x=5 give y=0? Does x=3 give y=โˆ’4?

Tasks

โœ๏ธ Your Task:
Use the starter code below. For each target_y in the list, a while loop searches
x in [0, 10] with step 0.01 and tracks the x where |y - target_y| is smallest.

   
targets = [-4.0, -3.0, 0.0, 3.0]
eps = 0.05

print(f'{"Target y":>10} | {"x found":>10} | {"y at x":>10} | {"Error":>8}')
print('-' * 46)

for target_y in targets:
    best_x    = 0.0
    best_diff = float('inf')

    i = 0
    while i <= 1000:          # 0.0 to 10.0 in steps of 0.01
        x    = i * 0.01       # compute x fresh โ€” avoids accumulated FP drift
        y    = x**2 - 6*x + 5
        diff = abs(y - target_y)
        if diff < best_diff:
            best_diff = diff
            best_x    = x
        i += 1

    y_found = best_x**2 - 6*best_x + 5
    print(f'{target_y:>10.1f} | {best_x:>10.4f} | {y_found:>10.4f} | {best_diff:>8.5f}')
# Extension: What happens if target_y = -5.0? # (Hint: the minimum of this parabola is y = -4)

1:10โ€“1:25 โ€” Part 3 โ€” Extension: Cube Root Search

Use exhaustive approximation to find x where xยณ = target โ€” the cube root of target. No math module needed: just use ** inside a while loop.

Extension

Type and run this code:

target = 50.0
eps    = 0.001
step   = 0.001
ans    = 0.0
count  = 0

while ans <= target:
    if abs(ans**3 - target) < eps:
        break
    ans   += step
    count += 1

if abs(ans**3 - target) < eps:
    print(f'Cube root of {target} โ‰ˆ {ans:.4f}')
    print(f'Python says:  {target**(1/3):.4f}')
    print(f'Error: {abs(ans - target**(1/3)):.6f}')
    print(f'Steps: {count:,}')
else:
    print('Failed to find cube root')
โœ๏ธ Your Task:

Try target = 8 and target = 125. Then change step to 0.01 โ€” how does accuracy change? Why?

1:25โ€“1:30 โ€” Wrap-Up & TA Check-Off

Show TA your Part 2 table (4 target y values โ†’ x values found). Discuss: how would you make this faster? (Preview: bisection search next week!)