69.x的平方根

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:输入: 4,输出: 2

示例 2:输入: 8,输出: 2(说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。)

 

1.二分法:就是大了就往小的找,小了就往大了找

int mySqrt(int x) 
{
    if(x == 1)
        return 1;
    int min = 0;
    int max = x;
    while(max-min>1)
    {
        int m = (max+min)/2;
        if(x/m<m)
            max = m;
        else
            min = m;
    }
    return min;
}

2.根据数学公式求:exp(0.5 * log(x))就是x的平方根的意思

int mySqrt(int x)
{
    int answer;
    if(x == 0)
        return 0;
    if(x == 1)
        return 1;
    
    answer = exp(0.5 * log(x));

    if(x >=(long long) (answer + 1) * (answer + 1))
    {
        return (long long)(answer + 1);
    }
    else
    {
        return (long long)answer;
    }
}

3.牛顿迭代法

int mySqrt(int x){
    if(x==0 || x==1) return x;
    long xn = x;
    while(xn > x / xn){
        xn = (xn + x/xn)/2;
    }
    return xn;
}

4.卡马克算法:作者是Nvidia的Gary Tarolli:http://www.matrix67.com/data/InvSqrt.pdf(改天折腾一下)

再加一个数学编程论坛:https://www.gamedev.net/

int InvSqrt(float x)
{
    float xhalf = 0.5f*x;
    int i = *(int*)&x; // get bits for floating VALUE 
    i = 0x5f375a86- (i>>1); // gives initial guess y0
    x = *(float*)&i; // convert bits BACK to float
    x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
    x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
    return (int)1/x;
}  

int mySqrt(int x){
    float p = (float)x;
    int ans=InvSqrt(p);
    if (ans*ans > x) return ans-1;
    return ans;
}

 

这题俨然进入数学范畴,头疼,自己摸着边用个二分法搞定。

posted @ 2020-07-16 23:14  Smah  阅读(256)  评论(0编辑  收藏  举报