不使用Math.sqrt实现求平方根


利用牛顿迭代法来求平方根。

设r是的根,选取作为r的初始近似值,过点做曲线的切线L,L的方程为,求出L与x轴交点的横坐标,称x1为r的一次近似值。过点做曲线的切线,并求该切线与x轴交点的横坐标,称为r的二次近似值。重复以上过程,得r的近似值序列,其中,称为r的次近似值,上式称为牛顿迭代公式。

对于x2=a,求a的平方根来说,相当于f(x)=x2-a,求曲线与x轴的交点。由上述结论可推导,xn+1=xn-f(x)/(2xn),假设要求平方根的数为a,xn+1约等于xn,则平方根xn+1约等于x-(x2-a)/(2x),即(x/2+a/2x)。

  1. 这时, 曲线f(t) = t2 - a 上对应的点为(t, t2- a), 过这个点切线的斜率为2t

  2. 如果我们把这一步迭代根的逼近距离(下图横轴红色表示)设为d, 那么结合1我们有: 2t = (t2 - a) / d

  3. 所以 d = (t - a/t)2, 这一步迭代后根坐标为(t - d, 0), 即(t + a/t)/2

  4. 判断精度,如果精度满足跳出迭代,如果不满足,重复step1.

public double sqrt(double x){
         //防止传入的参数小于0
         if(x<0){
               return Double.NaN;
         }
         double eps=1e-12;//保留小数点位数
         double t=x;
         //条件还可以这样写 while(Math.abs(t-x/t)>eps*t)
         while(Math.abs(t*t-x)>eps){
                 t=(t+x/t)/2.0;
         }
         return t;
}

进一步优化

//求x的平方根
public double sqrt(double x){
         //防止传入参数小于0
         if(x<0){
                 return Double.NaN;
         }
         double eps=1e-15; //精确度
         double m=x; //第i个值
         double n; //第i+1个值
         do{
                n=m;
                m=(m+x/m)/2.0;
         }while(Math.abs(m-n)>eps);
         return m;
}

扩展之后,求x的三次方根

长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn