求数值的n次方根

二分法

float SqrtByBisection(float n) //用二分法 
{ 
    if(n<0) //小于0的按照你需要的处理 
        return n; 
    float mid,last; 
    float low,up; 
    low=0,up=n; 
    mid=(low+up)/2; 
    do
    {
        if(mid*mid>n)
            up=mid; 
        else 
            low=mid;
        last=mid;
        mid=(up+low)/2; 
    }while(abs(mid-last) > eps);//精度控制
    return mid; 
}

二分法和系统函数性能差距几百倍。

牛顿迭代法

要求(t^frac {1} {n}),设所求值为(x),可列方程(x^n - t = 0),令(f(x) = x^n - t = 0),现使用泰勒公式在一个初始的点(x_0)处展开(f(x)),有

[f(x) = f(x_0) + f'(x_0)(x - x_0) = 0, x = x_0 - frac {f(x_0)} {f'(x_0)} $$, 这样计算出的$x$必然存在误差(除非你$x_0$初始值给定的就直接是精确结果,这个概率很小),那我们将计算出的$x$再作为第二次迭代的初始值$x_1$带入上式中,得到$x_2$,以此类推,即有: ]

x_1 = x_0 - frac {f(x_0)} {f'(x_0)},
x_2 = x_1 - frac {f(x_1)} {f'(x_1)},
x_3 = x_2 - frac {f(x_2)} {f'(x_2)},
...
x_{n+1} = x_n - frac {f(x_n)} {f'(x_n)}

[以上整个过程是一个不断迭代的过程,$x_{n+1} = x_n - frac {f(x_n)} {f'(x_n)}$即为牛顿迭代法的一个迭代关系式,这样的过程得到的$x_0,x_1,x_2,...,x_{n+1}$的序列也就是不断趋向所求结果的一组解,根据维基百科中的描述: > 已经证明,如果是连续的,并且待求的零点是孤立的,那么在零点周围存在一个区域,只要初始值位于这个邻近区域内,那么牛顿法必定收敛。 并且,如果不为0, 那么牛顿法将具有平方收敛的性能. 粗略的说,这意味着每迭代一次,牛顿法结果的有效数字将增加一倍。 因此,这样的过程是收敛的。 回到上面的式子,由$x_{n+1} = x_n - frac {f(x_n)} {f'(x_n)}$,当求平方根的时候,该递推式变为$x_{n+1} = x_n - frac {x^2_n - t} {2*x_n}$,化简,有$x_{n+1} = frac {1} {2} * (x_n + frac {t} {2*x_n})$,因此,写代码时就可以根据该式进行迭代求解。 例: 求根号2的值,假设初值$x_0 = 4$, ``` ( 4 + 2/4 ) / 2 = 2.25 ( 2.25 + 2/2.25 ) / 2 = 1.56944.. ( 1.56944..+ 2/1.56944..) / 2 = 1.42189.. ( 1.42189..+ 2/1.42189..) / 2 = 1.41423.. …. ``` 代码如下: ```cpp float SqrtByNewton(float x) { float val = x;//最终 float last;//保存上一个计算的值 do { last = val; val =(val + x/val) / 2; }while(abs(val-last) > eps); return val; } ```]

原文地址:https://www.cnblogs.com/ocean1100/p/9684434.html