c 实现int sqrt(int x)函数的细节讨论

来源:互联网 发布:oracle和mysql语法区别 编辑:程序博客网 时间:2024/06/07 02:39
  • 题目描述
    这里写图片描述

  • 分析
    注意该函数返回的数据类型,是int。那么我们应用二分查找即可实现。

  • 细节讨论
    于是我便写了如下所示的代码,然而运行超时了。

int mySqrt(int x) {    int low=0;    int high=x;    int mid,product;    while(low<=high){        mid=(low+high)/2;        product=mid*mid;        if(product==x)            break;        else if(product<x)            low=mid+1;        else            high=mid-1;    }    if(mid*mid>x)        return mid-1;    else        return mid;}

来看超时的案例说明,
这里写图片描述

那么问题来了,这么简单的一个代码怎么还会超时呢?代码逻辑没有错呀?

最终发现造成超时的真正原因是值溢出

来看下图的测试案例,
这里写图片描述
对于数23456789,将它循环除2的结果是11728394、5864197、…,怎么会有8399098如此大的运行结果呢?原因在这句代码,product=mid*mid; 两个大数相乘值溢出了,每次都溢出,直到不满足low<=high而输出结果。

所以,我们应该谨慎使用乘法,留意是否会有溢出情况发生。若有的话,可以把乘法换成除法防止溢出

将乘法替换为除法后的代码如下,

int mySqrt(int x) {    int low=1;    int high=x;    int mid;    if(x==0)        return 0;    while(low<=high){        mid=low+(high-low)/2;        if(mid==x/mid)            break;        else if(mid<x/mid)            low=mid+1;        else            high=mid-1;    }    if(mid>x/mid)        return mid-1;    else        return mid;}

基于同样‘防止溢出’的考虑,把mid=(low+high)/2;改为mid=low+(high-low)/2;会更安全。

小问题,大警醒,所以写下此文。

0 0
原创粉丝点击