Each rule below is asserted in the notes. Turn one off and the visualizer above runs the broken algorithm instead — same array, same target, same panels. Then switch to the invariant (lo, hi) tab with a rule still broken: all three have nothing left to break there, which is the case for preferring that skeleton.
mid is the side mid must round toward.lo = mid pairs with ceil, mid = lo + (hi - lo + 1) / 2. hi = mid pairs with floor, mid = lo + (hi - lo) / 2. Get it backwards and a two-element window can never shrink.
The loop converges to a candidate. If the predicate was never true anywhere, lo just sits at the edge of the range, unverified — and you return an index that answers nothing.
hi = n. “Last” queries do not.In a half-open loop mid < hi always, so n is never dereferenced. A closed loop takes mid up to hi itself — and there is no legal sentinel below 0 on the other end.