一、引言
不知道大家是否写过这样的一串代码,理论上能够计算满足该条件的所有数值,实际上过大的数却无法运算,从而导致错误的结果。今天我在写代码的时候无意察觉的一些东西。我在执行第一串代码的时候没有问题,但是若是把查找的值放大之后就没办法准确运行了。
int binary_search(int arr[], int k, int sz)
{
int left = 0;
int right = sz - 1;
while (left <= right)
{
int mid = (left + right) / 2;
//int mid = left+(right- left) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
return mid;
}
}
return -1;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 0;
scanf("%d", &k);
int sz = sizeof(arr) / sizeof(arr[0]);
int ret = binary_search(arr, k, sz);
if (ret == -1)
{
printf("找不到\n");
}
else
{
printf("找到了,下标是%d", ret);
}
return 0;
}
//上述代码的缺陷:在于int mid = (left + right)/2;的值如果很大就会造成结果错误
//修改成下列形式int avg = num1 + (num2 - num1)/2则可以避免这一情况
int main()
{
int num1 = 4563165847674;
int num2 = 4563165847676;
//int avg = (num1+num2)/2;
int avg = num1 + (num2 - num1) / 2;
printf("%d\n", avg);
return 0;
}
运行结果如下,显然不可能为一个负数。
二、思路讲解
大部分在看到我修改的代码是难以理解的,但是结合我的这张图就可以理解了。
首先:如果我们求的是a柱+b柱的和的一半的话,直接叠在一起再减半,会突破这个数值的界限。导致后续的计算出现错误。所以我们需要尽量降低它的高度(也就是数值大小)。
其次:我们可以观察到图中,我是讲b柱中大于a柱的高度的那部分划去一半安在了a的上面,最后形成了a和b一样的高度的柱形图。
最后:我们给自己的大脑一点点的思考时间就会明白,这样就跟脑筋急转弯一样的思路。
ps(大家可以尝试一下定义成long long类型的扩大数值上限的方法)