mid = left + ((right - left) >> 1) 是安全写法,因右移优先级低于加法,等价于“left 加半段距离”,既避免 left + right 溢出,又保留位移优化性能。

可以直接用 (right - left) >> 1 替代 (right - left) / 2,但必须确保 left 和 right 都是非负整数,且中点计算逻辑写成 mid = left + ((right - left) >> 1) —— 否则可能出错或失去优化意义。
为什么 mid = left + (right - left) >> 1 是安全的写法
右移运算符 >> 的优先级低于加法,所以 left + (right - left) >> 1 实际等价于 left + ((right - left) >> 1),不是 (left + (right - left)) >> 1。这正好符合我们“从 left 出发、加上半段距离”的语义。
这种写法同时满足两个关键需求:
- 避免
left + right溢出(尤其在int范围接近上限时) - 用位移替代除法,减少 CPU 指令周期 —— 在密集循环(如高频二分)中可测得微小但稳定的性能提升
注意:如果误写成 mid = (left + right) >> 1,虽然对正数结果相同,但溢出风险回归;而写成 mid = left + (right - left) / 2 就完全失去了位移优化价值。
>> 在负数上行为不一致,别碰边界外的索引
当 left 或 right 可能为负(比如自定义区间、调试时手动赋值),>> 的结果依赖平台和语言:C/C++ 中对有符号数右移是「算术右移」,高位补符号位;Java/JavaScript 中 >> 是有符号右移,>>> 才是无符号;Python 则没有算术右移,// 才是向下取整除法。
所以实际工程中应默认:
- 二分查找的
left、right始终 ≥ 0(数组下标天然满足) - 不把
>>用于任何可能含负值的中间计算,哪怕只是临时调试 - 若需支持负索引场景(极少见),直接用
Math.floor((left + right) / 2)或语言对应的安全整除
常见错误:把 或括号搞错导致逻辑偏移
实操中最容易踩的坑不是性能,而是手误:
- 写成
mid = left + (right - left) —— 这是左移,相当于乘 2,结果爆炸式变大 - 漏掉括号,写成
mid = left + right - left >> 1,因优先级变成(left + right - left) >> 1≡right >> 1,完全偏离本意 - 在 while 条件里用
却忘了调整 <code>right初始化(如设为nums.length),此时mid公式虽对,但边界逻辑已崩
建议统一使用带括号的显式形式:mid = left + ((right - left) >> 1),一眼可读,编译器也省心。
真正难的不是位移本身,而是确认整个二分框架里所有变量都落在非负整数域,并且每次 left、right 更新后仍保持 left ≤ right —— 这些地方出错,再快的 >> 也救不回逻辑正确性。










