C++中取两个数的平均数问题(left + (right - left) / 2)

(left + right) / 2(left + right) >> 1(left + (right - left) / 2)都是两数之和除以2,但在某些情况下,前两者可能会导致整数溢出问题,而后者不会。

1. (left + right) / 2 可能会导致溢出

  • leftright 都非常大时(接近 INT_MAX),left + right 的结果可能会超出 int 类型的最大值,导致整数溢出。
  • 例如,假设 left = 2^30right = 2^30,那么 left + right = 2^31,这是一个可能超出 int 范围的数(对于32位系统来说)。
  • 溢出后会得到一个负数或意外的结果,导致程序错误。

2. (left + (right - left) / 2) 避免溢出

  • 通过先计算 right - left,可以确保这个差值是非负且不会超出 int 范围。然后再除以 2,再加上 left,这样得到的结果也不会溢出。
  • 即使 leftright 都是接近 INT_MAX 的大数,这个公式也能安全地计算出中间位置。
  • 当然,(left + (right - left) / >> 1)这种写法在没有编译器优化的平台效果更佳,性能更好。

3. (left + right) >> 1

  • 位运算的右移 (left + right) >> 1 也存在和 (left + right) / 2 一样的溢出风险。
  • 这只是将除法换成了位运算,并不会解决溢出问题。

结论

使用 (left + (right - left) / 2) 是更安全的选择,可以避免在 leftright 非常大时的溢出问题。因此,这种写法更为推荐。

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值