我正在阅读二进制搜索...我知道找到中间值的传统方式就像
mid=(hi+lo)/2
但我也看到,为了避免溢出,中间值的计算就像那样
mid=lo+(hi-lo)/2
但为什么?我找不到实际的原因。任何人都可以举例说明理由吗? 它与其他问题不同,因为其他问题没有我想要的答案......
答案 0 :(得分:20)
假设您正在使用32位unsigned int
作为索引搜索4000000000元素数组。
第一步看起来似乎搜索到的元素(如果存在)将位于上半部分。 lo
的值为2000000000
,hi
的值为4000000000
。
hi + lo
溢出并生成小于预期6000000000
的值。它实际上产生6000000000-2 32 。因此,(hi + lo) / 2
是一个很小的值。它甚至不在lo
和hi
之间!
从那时起,搜索将是错误的(可能会认为该元素即使在那里也不存在)。
相比之下,即使使用此示例中的极值,lo + (hi - lo) / 2
也始终计算hi
和lo
之间的索引,正如算法所预期的那样。
答案 1 :(得分:4)
从数学上讲,它们是等价的。
在计算机术语中,mid=(hi+lo)/2
的操作较少,但mid=lo+(hi-lo)/2
是首选,以避免溢出。
假设您搜索的项目接近数组的末尾,则hi+lo
几乎为2*size
。由于size
几乎与最大索引一样大,2*size
因此hi+lo
可能会溢出。