Java 中二分查找取中间值的这个公式 int mid = low + (high - low)/2;,是数学中的什么公式啊?这个是什么原理啊?

2020-12-07 10:46:50 +08:00
 burnbrid

java 中二分查找取中间值的这个公式,是数学中的什么公式啊?我知道这样写是为了防止数值溢出,int mid = low + (high - low)/2; 但是我想知道这个是数学里面的什么公式? 正常来说求中间值不就是最大数 + 最小数 再除以 2 = 中间数。比如 1 和 9 。1 + 9 = 10 10 /2=5,5 刚好就是中间数,但是这个公式我搞不懂 int mid = low + (high - low)/2;

5276 次点击
所在节点    Java
43 条回复
ccvzz
2020-12-07 15:25:58 +08:00
@Mutoo 然而你的证明是错的。整数除法的话,你第一个等式就不对。let low=1,high=3,(low+high)/2=2,low/2+high/2=0+1=1
lrlz
2020-12-07 16:16:19 +08:00
夹逼准则
LGA1150
2020-12-07 17:18:37 +08:00
@redtea #18
负数下溢出会出问题
(Integer.MIN_VALUE * 2) >>> 1 会变成 0
redtea
2020-12-07 17:56:13 +08:00
@LGA1150 int mid = low + ((high - low)>>1);
hello2060
2020-12-07 18:04:58 +08:00
@ccvzz 不只整数乘法,他这浮点数也不对啊。
Raven316
2020-12-07 18:09:43 +08:00
小学毕业了吗
AmosAlbert
2020-12-07 18:21:58 +08:00
suikatw
2020-12-07 18:35:15 +08:00
@linauror 为什么这么写就可以防止溢出呢? high-low 感觉还是会溢出吧,比如 high = -INT_MAX, low=INT_MAX
venster
2020-12-07 18:47:20 +08:00
@imn1 看了这么多就没几个靠谱的,就你解释的最简洁明了了。
hello2060
2020-12-07 18:51:07 +08:00
@suikatw 同学,这是在说 2 分法写程序哇,left > right 的情况早就函数退出了啊
Ehend
2020-12-07 19:02:24 +08:00
。。。low+(high-low)/2,第一个 low 你理解为起点的偏移量就行,后面的部分就是取 1/2
suikatw
2020-12-07 19:11:11 +08:00
@hello2060 还是不懂,那改一下,high=INT_MAX, low=-INT_MAX 。int mid = low + (high - low)/2; 计算这条语句的时候算到括号里 high-low 不就溢出了么?
suikatw
2020-12-07 19:13:01 +08:00
@imn1 为什么会考虑 h+l 溢出但是不考虑 h-l 溢出呢?
hello2060
2020-12-07 19:19:39 +08:00
@suikatw 好吧,那就真的溢出了。你是对的。

但是二分法一般用在数组查找啊,left,right 起始值一般是 0 和 array.length - 1 啦,所以 right - low <= INT_MAX

high=INT_MAX, low=-INT_MAX 那肯定还是溢出了
Ehend
2020-12-07 19:20:49 +08:00
@suikatw 额,二分查找工程里用的话,哪有序号是负数的。。。即使从 0 开始计数,INT_MAX-0=INT_MAX,这不是还是没溢出吗。。。
suikatw
2020-12-07 19:28:41 +08:00
是我忽略了数组下标取值这个前提场景,确实可以防止溢出
wzcloud
2020-12-07 19:48:04 +08:00
数学中的公式。。。
mid=(low+high)/2=(low+high+low-low)/2=(2low+high-low)/2=low+(high-low)/2
jimmyismagic
2020-12-07 19:52:22 +08:00
我发现越简单的问题,讨论得越多,越没有价值的会,开得越长
flippydoo
2020-12-07 20:03:20 +08:00
义务教育的普及有待提高
lxilu
2020-12-08 00:19:03 +08:00
@hello2060 @ccvzz,@Mutoo 明明是数学证明

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/732827

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX