参考[C语言的整型溢出问题],自己稍作总结。
问题
先看一个简单的问题,求两个数的和。你可能会有如下的实现:
#include <iostream>
int add( int a, int b ){
return a+b;
}
int main( void ){
int a,b;
while( std::cin >> a >> b ){
int sum = add( a, b );
std::cout << sum << std::endl;
}
return 0;
}
这么写没有错误,但是,考虑这种情形。
a = 2100000000, b=2100000000。那么,很自然的就溢出了。所以,需要修改代码。怎么改?怎么判断是否溢出呢?这也是个技巧!
修改如下:
#include <iostream>
#include <climits>
int add( int a, int b ){
if( INT_MAX - a < b ){
std::cerr << "Overflow!" << std::endl;
exit(1); // 退出进程
}
return a+b;
}
int main( void ){
int a,b;
while( std::cin >> a >> b ){
int sum = add( a, b );
std::cout << sum << std::endl;
}
return 0;
}
再考虑一个bi_search的实现
int bi_search( int* arr, size_t len, int key ){
size_t low = 0;
size_t high = len - 1;
while( low <= high ){
size_t mid = (low+high)/2;
if( arr[mid] == key ) return mid;
else if( key < arr[mid] ) high = mid-1;
else low = mid+1;
}
return -1;
}
上文使用size_t也无可厚非,但是size_t有个很麻烦的一点就是0的情形,加入len = 0, 那么len - 1变成无符号数的最大值。代码可以继续下去。这是不行的。
所以,还是要这么实现:
int bi_search( int* arr, int len, int key ){
int low = 0;
int high = len - 1;
while( low <= high ){
int mid = (low+high)/2;
if( arr[mid] == key ) return mid;
else if( key < arr[mid] ) high = mid-1;
else low = mid+1;
}
return -1;
}
事实上,这么写任然是不行的。因为low+high还是可能会溢出。所以,不行。
防止溢出的写法应该是这样:
int bi_search( int* arr, int len, int key ){
int low = 0;
int high = len - 1;
while( low <= high ){
int mid = (low+high)/2;
if( arr[mid] == key ) return mid;
else if( key < arr[mid] ) high = mid-1;
else low = mid+1;
}
return -1;
}