Intuition What this page is
The parent note gave you two engines — bisection (a sign-change squeeze) and Newton-Raphson (a tangent chase). Engines are only trustworthy once you have driven them over every kind of road . This page enumerates every case a root-finder can hit, then works one example per case. When you finish, no scenario should surprise you.
This page is self-contained : everything it needs — the guard tests, the tangent formula, the error argument — is restated here in full before it is used. When a word is new, we rebuild it from zero.
Definition What is a "bracket"?
A bracket is just an interval [ a , b ] that we believe encloses a root — it "brackets" the crossing the way two hands cup a coin so it cannot escape. The technical condition that makes an interval a valid bracket is a sign change : f ( a ) and f ( b ) carry opposite ± signs. If f is continuous and its value flips from negative to positive across [ a , b ] , the curve must pass through zero somewhere between them (this is the Intermediate Value Theorem ). The name comes from that trapping picture: the root is bracketed — held on both sides.
Definition "One bit of precision" — what a
bit means here
A bit is one binary yes/no answer: it tells you which half of a range your unknown lives in. If you know a number lies in an interval of width w , and you learn it actually lies in a specific half of width w /2 , you have just gained one bit — one halving of your uncertainty. Bisection does exactly this each step, so "one bit of precision per step" literally means "each step halves the interval that could still hide the root". Ten bits ⇒ the interval shrank by 2 10 ≈ 1000 × ; that is why log 2 ( range / tolerance ) counts the steps.
Root-finding has a small number of situations that behave differently . Here is the full list. Each row's "Example" column names the section that works it (the labels C1…C10 match the headings below exactly).
#
Case class
What is special
Which method
Example
C1
Clean bracket, opposite signs
textbook bisection
bisection
C1
C2
Sign convention: which half survives
quadrant/sign bookkeeping
bisection
C2
C3
Endpoint is exactly a root
degenerate: f ( a ) = 0
bisection
C3
C4
Newton, good start, f ′ = 0
quadratic bliss
Newton
C4
C5
Newton near a flat spot (f ′ → 0 )
huge/undefined step
Newton
C5
C6
Newton that diverges / cycles
limiting bad behaviour
Newton
C6
C7
Double root (f = f ′ = 0 together)
convergence slows to linear
Newton
C7
C8
Real-world word problem
units, modelling
either
C8
C9
Exam twist: no derivative given
pick the robust engine
bisection
C9
C10
Invalid bracket (f ( a ) f ( b ) > 0 ), and midpoint hits root
error case + early exit
bisection
C10
Definition The three things a root-finder can meet
A sign change means f ( a ) and f ( b ) have opposite ± signs, so the curve crosses zero between them. A flat spot is where the slope f ′ ( x ) is (near) zero — the tangent is horizontal and points nowhere useful. A multiple root is where f touches the axis without crossing, so f and its slope f ′ vanish together; for a root of multiplicity m , in fact the first m − 1 derivatives all vanish there (f = f ′ = ⋯ = f ( m − 1 ) = 0 , but f ( m ) = 0 ). Our C7 example is the simplest case m = 2 .
We will meet all three, plus the pure error cases.
5 as the root of f ( x ) = x 2 − 5 on [ 2 , 3 ] .
Forecast: guess where 5 sits, and guess how many halvings you need for 3 decimals. (Answer near 2.236 ; roughly log 2 ( 1/0.001 ) ≈ 10 steps.)
Step 1 — Check the bracket. f ( 2 ) = 4 − 5 = − 1 , f ( 3 ) = 9 − 5 = 4 . Why this step? Bisection is only legal when f ( a ) f ( b ) < 0 ; here ( − 1 ) ( 4 ) = − 4 < 0 ✓ — a sign change, so by the Intermediate Value Theorem a root is trapped inside.
Step 2 — Midpoint. m = 2 2 + 3 = 2.5 , f ( 2.5 ) = 6.25 − 5 = 1.25 > 0 . Why? The midpoint splits the uncertainty exactly in half — that is the one move that guarantees each step buys one bit (one halving of uncertainty, as defined above).
Step 3 — Keep the half that still changes sign. f ( 2 ) = − 1 < 0 and f ( 2.5 ) = + 1.25 > 0 : the sign flip is on the left half. Keep [ 2 , 2.5 ] . Why? The root lives where the endpoints still disagree in sign.
Step 4 — Repeat. m = 2.25 , f = 0.0625 > 0 → keep [ 2 , 2.25 ] . m = 2.125 , f = − 0.484 < 0 → keep [ 2.125 , 2.25 ] . Why does each repeat help? Every step replaces one endpoint by the midpoint, so the interval width goes 1 → 0.5 → 0.25 → 0.125 = 2 n 1 — exactly halved each time, adding one bit of precision per step (linear convergence with ratio 2 1 ). The figure shows this as a stack of coloured bars: the top bar is [ 2 , 3 ] ; each bar below it is a sub-interval that sits inside the one above and is half its length ([ 2 , 2.5 ] , then [ 2 , 2.25 ] , then [ 2.125 , 2.25 ] ), and every bar straddles the red dashed vertical line at x = 5 ≈ 2.236 — so you can watch the root stay trapped while the bars close in on it.
Verify: the true root is 5 = 2.2360679 … ; after 4 steps our bracket [ 2.125 , 2.25 ] indeed contains it, width 0.125 = 2 3 1 . ✓
f ( x ) = x 3 − x − 2 on [ 1 , 2 ] : track the stored sign carefully.
Forecast: cubics can wiggle. Will this bracket keep pointing at the same root? (Yes — there is only one real root here, near 1.52 .)
Step 1 — Bracket. f ( 1 ) = 1 − 1 − 2 = − 2 , f ( 2 ) = 8 − 2 − 2 = 4 . Product − 8 < 0 ✓. Store f a = − 2 (negative).
Step 2 — Midpoint. m = 1.5 , f ( 1.5 ) = 3.375 − 1.5 − 2 = − 0.125 . Why store f a and compare to f m ? Compare stored f a = − 2 against f m = − 0.125 : same sign (both negative), so the crossing is not in the left half. Storing f a (rather than recomputing f ( a ) each loop) also saves function calls.
What "mixing conventions" concretely means. There are two consistent ways to decide which half to keep: (A) "keep the half whose endpoints have a sign change" — i.e. keep the left half [ a , m ] when f a ⋅ f m < 0 ; or (B) the mirror test "keep the right half [ m , b ] when f m ⋅ f b < 0 ". Each is correct on its own . The bug is using test (A) to decide but then updating the endpoint as if you had used test (B) — e.g. concluding "sign change is on the left" yet moving a up to m instead of moving b down to m . That single mismatch keeps the half that does not contain the root, and the next iteration silently converges to the wrong place (or hits the raise when the false bracket loses its sign change). The safe rule: pick one stored value (f a ), compare it to f m , and update the matching-sign endpoint — one convention, start to finish.
Step 3 — Move the left endpoint up. Because f a ⋅ f m > 0 , the root is in [ 1.5 , 2 ] . Set a = 1.5 , f a = − 0.125 . Why? We update the endpoint whose sign matched (a , since f a and f m agree), preserving one valid bracket.
Step 4 — Continue. m = 1.75 , f = 5.359 − 1.75 − 2 = 1.609 > 0 → now f a = − 0.125 and f m = + 1.609 disagree → keep [ 1.5 , 1.75 ] .
Verify: the real root of x 3 − x − 2 is 1.52137 … , which lies in [ 1.5 , 1.75 ] ✓. The stored-sign convention never lost it.
f ( x ) = x 2 − 4 on [ 2 , 5 ] — someone handed you a lucky endpoint.
Forecast: f ( 2 ) = 0 . Does the standard bracket test even run? (No! f ( 2 ) f ( 5 ) = 0 , not < 0 .)
Step 1 — The guard tests (stated in full here). Any correct bisection opens with three guards, in this order:
fa, fb = f(a), f(b)
if fa == 0 : return a # endpoint already an exact root
if fb == 0 : return b # other endpoint already an exact root
if fa * fb > 0 : # STRICTLY > 0, not >= 0
raise ValueError ( "f(a) and f(b) must have opposite signs" )
Why is the reject test > 0 and not >= 0? A product equal to zero means one endpoint is a root — that is not an error, it is a win. So > 0 rejects only the truly no-sign-change case, while the two == 0 checks above it catch the exact-root endpoints first. Why this exact order? The == 0 checks must come before the product test, so a zero endpoint is returned rather than falling through.
Step 2 — Trace our inputs. f ( 2 ) = 0 , so the very first guard if fa == 0 fires and returns a. Why order matters: had we reached fa*fb, we'd get 0 ⋅ 21 = 0 , which is not > 0, so no error would raise — but the loop would then run and could discard the exact zero. Checking fa == 0 first is what saves us.
Step 3 — Return. We return x ∗ = 2 immediately, zero iterations.
Verify: f ( 2 ) = 2 2 − 4 = 0 ✓ exact. Skipping the endpoint check on [ 2 , 5 ] would waste evaluations or lose the root.
Common mistake "A sign change means the endpoints can't be roots, so skip the check."
WHY it feels right: f ( a ) f ( b ) < 0 does rule out zero endpoints. The fix: the caller might pass an interval whose endpoint is exactly a root, giving f ( a ) f ( b ) = 0 . Always check endpoints before trusting the loop.
f ( x ) = x 2 − 2 , f ′ ( x ) = 2 x , from x 0 = 1.5 .
Forecast: count correct digits after each step — do they roughly double? (Yes: this is the hallmark of quadratic convergence.)
Step 1 — The update (derived here, not borrowed). The tangent line to f at x n is y = f ( x n ) + f ′ ( x n ) ( x − x n ) . Setting y = 0 and solving for x gives the Newton step x n + 1 = x n − f ′ ( x n ) f ( x n ) — the x-intercept of that tangent. For this f it simplifies to the Babylonian rule x n + 1 = 2 x n + x n 1 . Why this simplification? x − 2 x x 2 − 2 = x − 2 x + x 1 .
Step 2 — Iterate. The figure shows the blue parabola f ( x ) = x 2 − 2 , and at each guess a yellow straight tangent line; follow each tangent down to where it crosses the horizontal axis (a red dot) to read off the next guess.
x 1 = 2 1.5 + 1.5 1 = 0.75 + 0.6667 = 1.41667 (3 good digits).
x 2 = 2 1.41667 + 1.41667 1 = 0.708333 + 0.705882 = 1.414216 (6 digits).
Step 3 — Why so fast (with the second derivative made explicit). Write the error e n = x n − x ∗ where x ∗ = 2 . The convergence rate depends on the second derivative f ′′ , which measures how the slope itself changes — the curve's bending. Here f ( x ) = x 2 − 2 , so f ′ ( x ) = 2 x and f ′′ ( x ) = 2 (a constant: the parabola bends the same everywhere). The standard error bound is
e n + 1 ≈ 2 f ′ ( x ∗ ) f ′′ ( x ∗ ) e n 2 .
Plug in f ′′ ( x ∗ ) = 2 and f ′ ( x ∗ ) = 2 2 : the constant is 2 ⋅ 2 2 2 = 2 2 1 ≈ 0.354 . Because f ′ ( x ∗ ) = 2 2 = 0 , this bound holds and the error is proportional to e n 2 — it squares each step, so the number of correct digits roughly doubles.
Verify: 2 = 1.41421356 … ; x 2 = 1.414216 matches to 5 places ✓. Digit count went 3 → 6 : doubling confirmed. Check of the constant: e 1 = 1.5 − 2 ≈ 0.0858 , e 2 = x 2 − 2 ≈ 0.0000024 , and e 2 / e 1 2 ≈ 0.33 — close to the predicted 0.354 . ✓
f ( x ) = x 2 − 2 but starting at x 0 = 0.001 (almost the flat bottom-ish region of the slope).
Forecast: the slope f ′ ( 0.001 ) = 0.002 is tiny. Will the first step be small or gigantic? (Gigantic — dividing by a near-zero slope launches you far away.)
Step 1 — Compute the step. f ( 0.001 ) = 0.00 1 2 − 2 = − 1.999999 , f ′ ( 0.001 ) = 2 ( 0.001 ) = 0.002 . Step = 0.002 − 1.999999 = − 999.9995 . Why so large? The tangent is nearly horizontal, so its x-intercept is far off — a horizontal line meets the axis at infinity.
Step 2 — Jump. x 1 = 0.001 − ( − 999.9995 ) = 1000.0005 . See : the blue curve carries a shallow yellow tangent at the near-zero-slope point, and a red arrow shows the next guess flung far to the right along the axis.
Step 3 — Recovery. From x 1 = 1000 the slope is now huge and honest, so Newton does eventually come back — but it wasted iterations. If x 0 had been exactly 0 , then f ′ ( 0 ) = 0 and the code raises ZeroDivisionError — a flat tangent points nowhere.
Verify: step magnitude ∣ − 999.9995 ∣ = 999.9995 ✓, and x 1 = 1000.0005 ✓. The lesson: near a flat spot the step size blows up , the opposite of the tiny confident steps in C4.
f ( x ) = x 1/3 (cube root), starting anywhere except the root x ∗ = 0 .
Forecast: the only root is 0 . Will Newton walk toward it or away? (Away — it diverges geometrically.)
Step 1 — Derivative. f ( x ) = x 1/3 , so f ′ ( x ) = 3 1 x − 2/3 . Why check f ′ ? Newton divides by it; here it grows the wrong way.
Step 2 — The update simplifies. x n + 1 = x n − 3 1 x n − 2/3 x n 1/3 = x n − 3 x n 1/3 x n 2/3 = x n − 3 x n = − 2 x n . Why is this catastrophic? Each step multiplies x by − 2 : it flips sign and doubles the distance from the root.
Step 3 — Iterate from x 0 = 1 . x 1 = − 2 , x 2 = 4 , x 3 = − 8 , … See : the guess dots (red) sit on the axis and yellow curved arrows hop each guess to the next — 1 → − 2 → 4 → − 8 — leaping outward left, right, farther left, never toward the green root at 0 .
Verify: x n + 1 = − 2 x n gives ∣ x n ∣ = 2 n , which → ∞ ✓. Bisection on [ − 1 , 1 ] (with f ( − 1 ) = − 1 < 0 , f ( 1 ) = 1 > 0 ) would trap 0 safely — the eternal robustness-vs-speed trade-off.
Common mistake "Newton always converges — it's simply the better method."
WHY it feels right: when it works it doubles digits. The fix: bad start, near-zero slope, or an odd-power cusp like x 1/3 make it diverge or cycle. Robustness belongs to bisection.
f ( x ) = ( x − 3 ) 2 , a root of multiplicity two , from x 0 = 5 .
Forecast: at x ∗ = 3 , both f ( 3 ) = 0 and f ′ ( 3 ) = 0 . Does Newton still double its digits? (No — a double root demotes it to linear, halving the error only.)
Step 1 — Update. f ( x ) = ( x − 3 ) 2 , f ′ ( x ) = 2 ( x − 3 ) . So x n + 1 = x n − 2 ( x n − 3 ) ( x n − 3 ) 2 = x n − 2 x n − 3 = 2 x n + 3 . Why does this matter? The error obeys e n + 1 = 2 1 e n — linear , not quadratic.
Step 2 — Iterate. x 0 = 5 (error 2) → x 1 = 4 (error 1) → x 2 = 3.5 (error 0.5) → x 3 = 3.25 (error 0.25). Each step halves the error, exactly like bisection.
Step 3 — Why the slowdown? The quadratic bound e n + 1 ≈ 2 f ′ ( x ∗ ) f ′′ ( x ∗ ) e n 2 from C4 assumes f ′ ( x ∗ ) = 0 . At a double root f ′ ( x ∗ ) = 0 , that formula divides by zero and is invalid; the true rate collapses to linear. (For multiplicity m , both f and its first m − 1 derivatives vanish, and the linear rate becomes 1 − m 1 .)
Verify: x 1 = 2 5 + 3 = 4 ✓, x 2 = 2 4 + 3 = 3.5 ✓, x 3 = 3.25 ✓. Errors 2 , 1 , 0.5 , 0.25 — ratio 2 1 , linear ✓.
Worked example A projectile's height is
h ( t ) = 20 t − 4.9 t 2 metres, with t in seconds. When does it hit the ground (h = 0 , other than launch)?
Forecast: launch is t = 0 ; landing should be a few seconds later (guess near 4 s).
Step 1 — Set up the root problem. We want h ( t ) = 0 , i.e. t ( 20 − 4.9 t ) = 0 . Why factor? One root is the trivial t = 0 ; the physical landing is the other factor's root.
Step 2 — Bracket the landing. h ( 3 ) = 60 − 44.1 = 15.9 > 0 , h ( 5 ) = 100 − 122.5 = − 22.5 < 0 : sign change on [ 3 , 5 ] ✓. Why bisection here? A clean bracket exists and we want a guaranteed answer with correct units.
Step 3 — Squeeze.
m = 4 : h ( 4 ) = 80 − 78.4 = 1.6 > 0 . Why keep [ 4 , 5 ] ? h ( 4 ) > 0 and h ( 5 ) < 0 still disagree in sign, so the crossing is on the right half.
m = 4.5 : h ( 4.5 ) = 90 − 99.225 = − 9.225 < 0 . Why keep [ 4 , 4.5 ] ? Now h ( 4 ) > 0 and h ( 4.5 ) < 0 disagree, so the root is in the left half. Converging toward t ∗ = 20/4.9 .
Verify (algebra + units): solving 20 − 4.9 t = 0 gives t ∗ = 20/4.9 = 4.0816 … seconds, which sits in [ 4 , 4.5 ] ✓. Units: [ m⋅s − 1 ] / [ m⋅s − 2 ] = [ s ] ✓ — the answer is a time, as it must be.
Worked example "Find a root of
f ( x ) = e x + x on [ − 1 , 0 ] . You are not given f ′ ." Which engine, and why?
Forecast: Newton needs f ′ ; can you get away without differentiating? (Yes — use bisection, or the derivative-free Secant method .)
Step 1 — Read the constraint. No f ′ ⇒ Newton is off the table unless you differentiate by hand. Why? The Newton update divides by f ′ ( x n ) ; without it there is nothing to divide by.
Step 2 — Bracket. f ( − 1 ) = e − 1 − 1 = 0.3679 − 1 = − 0.6321 < 0 , f ( 0 ) = 1 + 0 = 1 > 0 : sign change ✓. Why this is enough? Bisection needs only f values and a sign flip — no calculus.
Step 3 — Squeeze. m = − 0.5 : f = e − 0.5 − 0.5 = 0.6065 − 0.5 = 0.1065 > 0 → keep [ − 1 , − 0.5 ] . m = − 0.75 : f = 0.4724 − 0.75 = − 0.2776 < 0 → keep [ − 0.75 , − 0.5 ] . Converging near − 0.567 .
Verify: the true root of e x + x = 0 is x ∗ = − 0.567143 … (the negative Omega constant), which lies in [ − 0.75 , − 0.5 ] ✓. Exam-safe choice: bisection , because it demands zero derivatives.
Worked example Two edge behaviours of the bisection loop itself: (a)
f ( a ) f ( b ) > 0 handed in as a "bracket", and (b) a midpoint that is exactly a root, needing the early exit if fm == 0: return m.
Forecast: what should the code do in each case? (a) refuse with an error; (b) stop instantly and return the midpoint.
Step 1 — Invalid bracket (a). Take f ( x ) = x 2 − 2 on [ 2 , 3 ] . f ( 2 ) = 2 > 0 , f ( 3 ) = 7 > 0 : product 14 > 0 . Why refuse? No sign change means the Intermediate Value Theorem gives no guarantee of a root inside — the guard if fa*fb > 0: raise ValueError (stated in full in C3) fires. Continuing would be meaningless: bisection cannot invent a crossing that is not bracketed.
Step 2 — Midpoint hits the root (b). Take f ( x ) = x 2 − 4 on [ 1 , 3 ] . f ( 1 ) = − 3 < 0 , f ( 3 ) = 5 > 0 : valid bracket. The midpoint is m = 2 1 + 3 = 2 , and f ( 2 ) = 0 exactly . Why an early exit? The loop body carries the guard if fm == 0 or (b - a)/2 < tol: return m. Without the fm == 0 test, the code would compare fa*fm — but f a ⋅ 0 = 0 is neither <0 nor handled, so it would fall into the else branch and walk away from the exact root . The early exit catches this lucky bullseye.
Step 3 — Contrast. Case (a) returns no answer (an error — the input was illegal); case (b) returns the exact answer in one step . Both are handled by two tiny guards; this example shows precisely when each fires.
Verify: (a) f ( 2 ) f ( 3 ) = 2 ⋅ 7 = 14 > 0 ✓ so raise triggers. (b) f ( 2 ) = 2 2 − 4 = 0 ✓ exact, so if fm == 0: return 2 fires — and the true root of x 2 − 4 on [ 1 , 3 ] is indeed 2 . ✓
Recall Quick self-test across the matrix
Which cell breaks Newton's quadratic convergence even with a perfect start? ::: C7 — a double root, because f ′ ( x ∗ ) = 0 demotes it to linear.
Why does starting at x 0 = 0.001 (C5) send Newton far away? ::: The slope f ′ is near zero, so the tangent is nearly flat and its x-intercept is enormous — a giant step.
On f ( x ) = x 1/3 (C6), what does the Newton update reduce to? ::: x n + 1 = − 2 x n , doubling the distance and flipping sign each step — pure divergence.
Given no derivative (C9), name two safe options. ::: Bisection or the secant method — both need only f values.
What two guards handle the bisection edge cases in C10? ::: if fa*fb > 0: raise (no valid bracket) and if fm == 0: return m (midpoint is exactly a root).
What does "one bit of precision" mean for bisection? ::: One halving of the uncertainty interval — a single yes/no answer about which half hides the root.
For a root of multiplicity m , which derivatives vanish there? ::: f = f ′ = ⋯ = f ( m − 1 ) = 0 but f ( m ) = 0 .
Mnemonic The four Newton dangers, "SLoW-D"
S tart too far · Lo w (flat) slope f ′ ≈ 0 · W iggly/odd cusp (cycles/diverges) · D ouble root (slows to linear). When any appear, fall back to bisection.
See also the parent note , Fixed-point iteration for another view of iteration, scipy.optimize for production tooling, and Floating point arithmetic for why f(m)==0 almost never happens exactly.