› 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 › Bisection search: Reason for subtracting 1 in case of high and adding 1 in case of low with firstnum
- This topic is empty.
-
AuthorPosts
-
July 4, 2025 at 1:25 pm #5019
Bisection search: Reason for subtracting 1 in case of high and adding 1 in case of low with firstnum
byu/DigitalSplendid inlearnpythonGreat question! You’re trying to understand this key part of bisection (binary) search:
elif firstnum > gemnum: high = firstnum - 1 else: low = firstnum + 1Let’s walk through why we subtract 1 or add 1 to narrow the search range properly.
🎯 The Goal of Bisection Search
You’re looking for a target value (
gemnum) in a sorted range.Each time, you check the middle number (
firstnum = (low + high) // 2), and based on the result:- If it’s too high → eliminate the right half
- If it’s too low → eliminate the left half
🔍 Why
high = firstnum - 1- When
firstnum > gemnum, it means the number we want is strictly less thanfirstnum. - So we eliminate
firstnumitself and everything above it. - That’s why we set the new upper bound (
high) tofirstnum - 1.
🧠 Example:
Suppose
gemnum = 30low = 0,high = 100→firstnum = 50- 50 > 30 → we know
gemnumis somewhere between 0 and 49 - So we set:
high = 50 - 1 = 49
🔍 Why
low = firstnum + 1- When
firstnum < gemnum, it means the number we want is strictly greater thanfirstnum. - So we eliminate
firstnumitself and everything below it. - That’s why we set the new lower bound (
low) tofirstnum + 1.
🧠 Example:
Suppose
gemnum = 70low = 0,high = 100→firstnum = 50- 50 < 70 →
gemnummust be between 51 and 100 - So we set:
low = 50 + 1 = 51
🧩 Why Not Just Set
high = firstnumorlow = firstnum?If you do not exclude
firstnum(by subtracting or adding 1), your loop might:- get stuck checking the same number over and over
- never terminate, especially if
gemnumisn’t in the list/range
Using
-1and+1guarantees that you shrink the search space each time and avoid infinite loops.
✅ Final Summary:
Condition What It Means What to Do Why? firstnum > gemnumGuess too high high = firstnum - 1Eliminate firstnumand everything above itfirstnum < gemnumGuess too low low = firstnum + 1Eliminate firstnumand everything below itfirstnum == gemnumCorrect guess breakFound it!
Absolutely — let’s explore this more deeply with a concrete example, to show why using
high = firstnumorlow = firstnum(without-1or+1) can break the algorithm.
❗ The Core Problem: Infinite Loop or Stagnation
If you don’t update your bounds strictly (by adding or subtracting 1), you may not reduce the search range. This can lead to the loop checking the same
firstnumrepeatedly, resulting in:- an infinite loop if the target isn’t found
- a stuck search that never converges
📌 Example: Target not present (e.g.,
gemnum = 99.5)Let’s pretend the list or range only includes integers from
low = 0tohigh = 100.You’re searching for
gemnum = 99.5(not actually in the range), and you’re using this wrong logic:if firstnum > gemnum: high = firstnum # ❌ no -1 else: low = firstnum # ❌ no +1Let’s walk through:
❌ Faulty Version (no -1/+1)
Initial range:
low = 0,high = 100firstnum = (0 + 100) // 2 = 50→ 50 < 99.5
→low = 50firstnum = (50 + 100) // 2 = 75→ 75 < 99.5
→low = 75firstnum = (75 + 100) // 2 = 87→ 87 < 99.5
→low = 87firstnum = (87 + 100) // 2 = 93→ 93 < 99.5
→low = 93firstnum = (93 + 100) // 2 = 96→ 96 < 99.5
→low = 96firstnum = (96 + 100) // 2 = 98→ 98 < 99.5
→low = 98firstnum = (98 + 100) // 2 = 99→ 99 < 99.5
→low = 99firstnum = (99 + 100) // 2 = 99again
→low = 99(no change!)- Infinite loop:
firstnumwill keep returning 99 forever!
✅ Correct Version (with +1 / -1)
if firstnum > gemnum: high = firstnum - 1 else: low = firstnum + 1Let’s see what happens now:
Initial range:
low = 0,high = 100firstnum = 50→ 50 < 99.5 →low = 51firstnum = 75→ 75 < 99.5 →low = 76firstnum = 88→low = 89firstnum = 94→low = 95firstnum = 97→low = 98firstnum = 99→low = 100firstnum = 100→ 100 > 99.5 →high = 99
✅ Now:
low = 100,high = 99→ loop exits.
We correctly detect that 99.5 isn’t found in the integer list.
💡 Summary: Why
-1and+1Are NecessaryWithout -1/+1With -1/+1May recheck same firstnumAlways narrows search range Can cause infinite loops Always converges or exits Range doesn’t shrink Range shrinks every loop
🧠 Rule of Thumb:
- When you eliminate a half, you must fully exclude the midpoint (
firstnum) that’s already been tested. - Otherwise, your search space never shrinks — and that’s fatal in divide and conquer.
Great! Let me walk you through a diagram-based explanation to visually show how binary search works with and without the
+1/-1bounds adjustment.
🔍 Scenario: We’re searching for
gemnum = 99.5- Our list (or range) has integers only, from
0to100 gemnum = 99.5is not in the list- Let’s compare two strategies:
❌ Wrong Method – No
+1or-1if firstnum > gemnum: high = firstnum else: low = firstnumStep lowhighfirstnum = (low+high)//2Comparison Updated Range 1 0 100 50 50 < 99.5 → go up low = 50 2 50 100 75 75 < 99.5 low = 75 3 75 100 87 87 < 99.5 low = 87 4 87 100 93 93 < 99.5 low = 93 5 93 100 96 96 < 99.5 low = 96 6 96 100 98 98 < 99.5 low = 98 7 98 100 99 99 < 99.5 low = 99 8 99 100 99 99 < 99.5 low = 99 again 9 99 100 99 99 < 99.5 low = 99 again 🔁 This loop gets stuck!
firstnum= 99 forever.
❗ The range doesn’t shrink — infinite loop.
✅ Correct Method – With
+1/-1if firstnum > gemnum: high = firstnum - 1 else: low = firstnum + 1Step lowhighfirstnumComparison Updated Range 1 0 100 50 50 < 99.5 low = 51 2 51 100 75 75 < 99.5 low = 76 3 76 100 88 88 < 99.5 low = 89 4 89 100 94 94 < 99.5 low = 95 5 95 100 97 97 < 99.5 low = 98 6 98 100 99 99 < 99.5 low = 100 7 100 100 100 100 > 99.5 high = 99 💥
low = 100,high = 99→ conditionlow <= highfails
✅ Loop exits: target not found
🎯 Visualization Summary:
Wrong version: [ stuck at 99 ] low: 99 high: 100 mid: 99 ← stuck here forever! Correct version: [ 98 ] → 99 → 100 → exit low: grows high: shrinks
🧠 Key Rule:
Always eliminate the middle value after checking it.
high = mid - 1if too highlow = mid + 1if too low
That guarantees:
✅ You never recheck the same value
✅ The range shrinks every loop
✅ You either find the value or exit cleanly
Excellent — let’s now dive deeply with examples to show what happens if you don’t use
high = mid - 1orlow = mid + 1in binary search, and instead do:high = mid low = midThis logic fails because it doesn’t exclude the midpoint (
mid) — which leads to:- infinite loops
- repeated guesses
- never narrowing the search range
🔁 Example 1: Target not present in the list (e.g.,
gemnum = 99.5)Let’s search in this range:
low = 0 high = 100 gemnum = 99.5 # Not an integer; not in the listLet’s simulate wrong code:
if mid > gemnum: high = mid # ❌ wrong — should be mid - 1 else: low = mid # ❌ wrong — should be mid + 1
Step-by-step simulation:
Step lowhighmid = (low + high)//2Comparison Updated Range 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 = 999 99 100 99 99 < 99.5 still 99 🔁 … … 99 loop forever no progress 💥 It’s stuck checking
mid = 99forever — infinite loop!
💡 Why This Happens
When you do:
low = mid # or high = midYou’re keeping the same midpoint in the next iteration, unless the range changes. So
midgets calculated as the same value again and again.
🛠️ Fix It with
+1and-1Let’s use the correct binary search update:
if mid > gemnum: high = mid - 1 else: low = mid + 1Same example, now correctly:
Step lowhighmidAction 1 0 100 50 low = 51 2 51 100 75 low = 76 3 76 100 88 low = 89 4 89 100 94 low = 95 5 95 100 97 low = 98 6 98 100 99 low = 100 7 100 100 100 high = 99 ❌ low > highLoop ends correctly ✅ Result: we cleanly exit, knowing the number is not in the list.
🔁 Example 2: Target is present in the list
Suppose we search for
gemnum = 99, and again mistakenly do:if mid > gemnum: high = mid else: low = midHere’s what happens:
Step low high mid Outcome 1 0 100 50 low = 50 2 50 100 75 low = 75 3 75 100 87 low = 87 4 87 100 93 low = 93 5 93 100 96 low = 96 6 96 100 98 low = 98 7 98 100 99 low = 99 8 99 100 99 low = 99 again! 🔁 … … 99 Infinite loop 🔁 You never actually “accept” the correct guess, because you’re not shrinking the search space.
✅ Takeaway:
Binary search works ONLY if you eliminate the current mid from future consideration:
# Correct pattern if mid > target: high = mid - 1 elif mid < target: low = mid + 1 else: found itOtherwise, your range never shrinks, and the loop never ends — especially when:
- the value isn’t in the list
- or the midpoint repeats without exclusion
-
AuthorPosts
- You must be logged in to reply to this topic.


