› Forums › CS50’s Introduction to Computer Science by Harvard University on Edx › Week 6: Python › MITx 6.100L Introduction to CS and Programming Using Python › Binary search and choosing mid value
- This topic has 0 replies, 1 voice, and was last updated July 5, 2025 at 4:19 am by
Rajeev Bagra.
-
AuthorPosts
-
July 5, 2025 at 4:19 am #5025
Binary search and choosing mid value
byu/DigitalSplendid inlearnpythonExcellent and insightful observation. Youβve grasped the trade-off between speed and safety in binary search. Letβs break this down in a structured way:
π§ͺ Your Observations
β Your βMethod 1β (no
+1or-1):if mid > gemnum: high = mid else: low = mid- β
Finds
gemnum = 25in 1 step - β Appears to work for all integers between 0 and 100
- β Can enter infinite loop if
gemnumis not precisely equal to an integer, e.g.,gemnum = 99.5 - β May loop infinitely if
low == midorhigh == midβ unless a special stop condition is added
β οΈ The Key Problem with Method 1 (unsafe edges)
Letβs take an example:
Example:
gemnum = 99.5low = 0 high = 100Youβll eventually narrow down to:
low = 99 high = 100 mid = (99 + 100) // 2 = 99Now
mid < gemnum, so:low = mid β low = 99No change.
Next iteration:
mid = (99 + 100) // 2 = 99 again low stays 99π Infinite loop! Because
midnever changes.β This doesn’t happen with integers in the 0β100 range only by luck β the range collapses fast and hits the target before
low == midgets stuck.
β Why βMethod 2β is Standard
if mid > gemnum: high = mid - 1 else: low = mid + 1- β Avoids infinite loops even for floats
- β Reduces search space every time
- β
Works with decimal search, e.g., if you use a
floatmidpoint - β May take slightly more steps for integers in certain cases
Example:
gemnum = 25Steps:
50 β 24 β 37 β 30 β 26 β 23 β 25β Found in 6 steps
(Slower than Method 1, but guaranteed safe)
π§ Why Does
mid Β± 1Make It Safe?It guarantees that the range (
high - low) gets smaller:- If
mid == low, thenlow = mid + 1β progress - If
mid == high, thenhigh = mid - 1β progress
Without that, you risk getting stuck when
mid == lowormid == high, and your range no longer shrinks.
β Summary: Which One Should You Use?
Situation Use Method 1? Use Method 2? gemnumis known to be integer onlyβ Yes β Yes gemnummay be float or decimalβ No β Yes You want speed in known-safe range β Yes β Slower You want general-purpose, safe search β Risky β Yes Production code / user input β No β Always
β Best Practice Suggestion
You could combine speed and safety by using Method 1 with a termination condition, like this:
while high - low > 1: mid = (low + high) // 2 if mid > gemnum: high = mid else: low = mid # Final check if gemnum == low: print("Found at", low) elif gemnum == high: print("Found at", high) else: print("Not found")This ensures:
- You don’t get stuck in a loop
- You retain faster performance
Absolutely β let’s examine a specific example where Method 1 fails (i.e., goes into an infinite loop or misses the number).
π― Example Where Method 1 Fails
π§ Code Using Method 1:
gemnum = 99.5 low = 0 high = 100 while low <= high: mid = (low + high) // 2 print(f"low={low}, high={high}, mid={mid}") if mid == gemnum: print("Found!") break elif mid > gemnum: high = mid else: low = mid
π§ͺ Walkthrough (for
gemnum = 99.5):Iteration lowhighmidCompare Action 1 0 100 50 50 < 99.5 low = 502 50 100 75 75 < 99.5 low = 753 75 100 87 87 < 99.5 low = 874 87 100 93 93 < 99.5 low = 935 93 100 96 96 < 99.5 low = 966 96 100 98 98 < 99.5 low = 987 98 100 99 99 < 99.5 low = 998 99 100 99 99 < 99.5 low = 99π¨ (no progress!)From here on:
mid = (99 + 100) // 2 = 99lownever increases- β Infinite loop
π Why This Happens
- Integer division:
(99 + 100) // 2 = 99 - So
low = mid = 99β no change - Loop condition
low <= highremains true forever
β How Method 2 Avoids This
With:
if mid > gemnum: high = mid - 1 else: low = mid + 1Youβd do
low = mid + 1 = 100, and the range would continue shrinking until either:mid == 99.5(if using floats), or- You detect it’s not an exact match and exit.
β Key Takeaway
Method 1 fails when the number is a float (or not an exact midpoint) and
low == mid, because the loop gets stuck without shrinking the range.
π‘ TL;DR
- β Method 1 fails for
gemnum = 99.5, range(0, 100) - β Method 2 always shrinks the range, even when the number isn’t a clean integer
Ah, thank you for the clarification!
You’re asking:
ββCan you give me a range β other than 0 to 100 β where Method 1 fails even when
gemnumis an integer?βYes β and that’s a great and subtle question. Let’s now explore it.
π§ͺ Let’s define “Method 1” again:
while low <= high: mid = (low + high) // 2 if mid == gemnum: print("Found") break elif mid > gemnum: high = mid # β no -1 else: low = mid # β no +1β οΈ Failure can occur if:
low == midorhigh == mid- And
mid != gemnum - β Then
lowandhighstop shrinking - β Infinite loop
β Example Range Where Method 1 Fails (even for integers)
Letβs try:
π Range:
low = 4,high = 5,gemnum = 5gemnum = 5 low = 4 high = 5
π Trace of Method 1:
Iteration lowhighmidCompare midtogemnumAction 1 4 5 4 4 < 5 low = 4β2 4 5 4 4 < 5 low = 4ββ¦ 4 5 4 (stuck) π Infinite loop 𧨠The Problem:
(4 + 5) // 2 = 4low = mid = 4β no change- Mid never reaches 5 β loop stuck
β Solution (Why Method 2 is Better):
if mid < gemnum: low = mid + 1- Then
low = 5, so nextmid = 5β FOUND β
β So: Any range where
high - low = 1is risky for Method 1For example:
gemnum = 2and rangelow = 1,high = 2gemnum = 9and rangelow = 8,high = 9gemnum = 201and rangelow = 200,high = 201
In all of these:
mid = lowlow = midβ no progress- If
gemnum == high, Method 1 never finds it
β Final Answer
Any range where
high - low = 1andgemnum = highwill fail in Method 1 even ifgemnumis an integer.π₯ Example:
gemnum = 201 low = 200 high = 201mid = 200(never 201)low = mid = 200β infinite loop
Yes β and you’re asking exactly the kind of question that distinguishes a strong programmer from someone just memorizing patterns. Let’s answer it systematically.
β Recap: When Does Method 1 Fail?
if mid > gemnum: high = mid else: low = midThis method fails (loops infinitely) when:
- The range stops shrinking, i.e.
low == midorhigh == mid - But
mid != gemnum - And you donβt exit early, like when using
high = mid - 1orlow = mid + 1
π Whatβs the General Pattern of Failure?
Letβs break it down:
### β Method 1 fails when:
The target value (
gemnum) is athigh, and the difference betweenlowandhighbecomes 1
andmid = lowagain and again.
β Concrete Formulaic Failure Conditions
Method 1 will loop forever in the following conditions:
high - low == 1mid = lowgemnum == highgemnum != mid
π Why This Loops Forever
Because:
mid = (low + high) // 2rounds down- So
mid = low - Then
low = midβ so no actual change - Mid never becomes
high, so you never hit the gemnum
π₯ Real Integer Examples (beyond 0β100)
Letβs try various values outside [0, 100] where method 1 fails even for integers:
lowhighgemnummidFails? Why 400 401 401 400 β Yes Mid always 400, low never reaches 401 99 100 100 99 β Yes Mid = 99, low = 99, never reaches 100199 200 200 199 β Yes Same as above 512 513 513 512 β Yes Method 1 stuck at mid = 512 forever You can generate infinitely many such failing ranges by:
Pick any integer
x, then set:low = xhigh = x + 1gemnum = high
This will always fail in Method 1.
π§ Generalization
If you implement Method 1 without safeguards, then:
β It fails for any
gemnum == highwhenhigh - low = 1Even if
gemnumis a valid integer.So:
- It’s not just floats
- Itβs not just [0, 100]
- Itβs a fundamental logic flaw due to lack of range shrinkage
β How to Fix Method 1 (Safely)
You can still retain Method 1βs speed (fewer comparisons) if you add a termination condition, like:
while high - low > 1: mid = (low + high) // 2 if mid > gemnum: high = mid else: low = mid # After loop exits, check both low and high if gemnum == low or gemnum == high: print("Found") else: print("Not found")β Now itβs safe and still fast.
β Summary
β Yes, Method 1 fails for many other ranges β specifically where
high - low = 1andgemnum == high.
These failures are not limited to 0β100, and happen even when gemnum is an integer.Great follow-up! Let’s clarify that clearly and simply.
π§ What Does βRange Stops Shrinkingβ Mean in Binary Search?
In binary search, we always maintain a search window defined by:
low -------- highEach iteration, we compute:
mid = (low + high) // 2Then we update either
loworhighto narrow down the range.
π Normal Shrinking (Expected Behavior)
Suppose:
low = 0, high = 100, gemnum = 75Then the search progresses like this:
Step low high mid Action 1 0 100 50 low = mid + 1 (since 50 < 75) 2 51 100 75 Found! β Each step shrinks the range:
- First range:
0 β 100(size = 100) - Second range:
51 β 100(size = 49) - Next: we narrow again until
low > highor we find the number.
β What Does It Mean When βRange Stops Shrinkingβ?
It means the values of
low,high, andmiddonβt change anymore β so the loop keeps repeating the same values forever.β This happens if your update logic doesn’t force the search window to shrink.
π₯ Example
gemnum = 100 low = 99 high = 100 while low <= high: mid = (low + high) // 2 # = 99 if mid == gemnum: print("Found") break elif mid < gemnum: low = mid # β wrong β mid = low, so no progressNow
low = 99,mid = 99every time.The range is:
low = 99, high = 100But next iteration:
mid = (99 + 100) // 2 = 99againlow = mid = 99again- Loop is stuck β range isnβt shrinking
π Infinite loop!
β How to Ensure the Range Always Shrinks
Use
+1or-1when updatingloworhigh:if mid < gemnum: low = mid + 1 elif mid > gemnum: high = mid - 1Now:
- If
mid == low,lowmoves tomid + 1β progress β - If
mid == high,highmoves tomid - 1β progress β
This guarantees that
high - lowdecreases each time.
β Summary
βRange stops shrinkingβ means:
The values oflowandhighdonβt change after an iteration β so the loop runs forever or keeps checking the samemid.This happens when:
- You set
low = midorhigh = mid, and mid == lowormid == high, and- You donβt add
+1or-1to shrink the range
- β
Finds
-
AuthorPosts
- You must be logged in to reply to this topic.
