整型溢出的问题

本文探讨了C语言中整型数据溢出的问题,并通过具体示例展示了如何避免整型加法及二分查找过程中的溢出。文章提供了实用的代码片段来帮助读者理解并解决这一常见编程难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考[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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值