[筆試題] 不使用庫函數sqrt實現求一個數的平方根

看到這題第一想法就是二分,並且很快就能寫出代碼來:

double SQRT_Binary(double n)
{
    double s = 0, t = n;
    if(n < 1) t = 1;
    while(t - s > inf)
    {
        double mid = (t + s) / 2;
        if(mid * mid > n)
            t = mid;
        else
            s = mid;
    }
    return (t + s) / 2;
}

不過還有個速度更好的方法,就是牛頓迭代法


知道了原理就很簡單了,這個題目的函數是f(x² - n) = 0,套用一下上述公式,很快就能得到答案了:

double SQRT_Newton(double n)
{
    double x0 = n;
    double x1;
    while(1)
    {
        //x1 = -(x0 * x0 - n) / (2 * x0) + x0;
        x1 = (x0 * x0 + n) / (2 * x0);
        double val = x1 * x1 - n;
        if(val <= inf && val >= -inf)
            return x1;
        x0 = x1;
    }
    return 0;
}

下面是完整代碼:
#include<iostream>
#include<cmath>
using namespace std;

#define inf 1e-7

double SQRT_Binary(double n)
{
    double s = 0, t = n;
    if(n < 1) t = 1;
    while(t - s > inf)
    {
        double mid = (t + s) / 2;
        if(mid * mid > n)
            t = mid;
        else
            s = mid;
    }
    return (t + s) / 2;
}

double SQRT_Newton(double n)
{
    double x0 = n;
    double x1;
    while(1)
    {
        //x1 = -(x0 * x0 - n) / (2 * x0) + x0;
        x1 = (x0 * x0 + n) / (2 * x0);
        double val = x1 * x1 - n;
        if(val <= inf && val >= -inf)
            return x1;
        x0 = x1;
    }
    return 0;
}

int main()
{
    printf("%.6lf\n%.6lf\n", sqrt(0.5), SQRT_Binary(0.5));
    printf("%.6lf\n%.6lf\n", sqrt(3), SQRT_Binary(3));
    printf("\n");
    printf("%.6lf\n%.6lf\n", sqrt(0.5), SQRT_Newton(0.5));
    printf("%.6lf\n%.6lf\n", sqrt(3), SQRT_Newton(3));
    getchar();
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章