快速浮点开方运算

二分法

浮点开方也就是给定一个浮点数x,求根号x。这个简单的问题有很多解,我们从最简单最容易想到的二分开始讲起。利用二分进行开平方的思想很简单,就是假定中值为最终解。假定下限为0,上限为x,然后求中值;然后比较中值的平方和x的大小,并根据大小修改下限或者上限;重新计算中值,开始新的循环,直到前后两次中值的距离小于给定的精度为止。需要注意的一点是,如果x小于1,我们需要将上限置为1,原因你懂的
代码如下:

#define eps 2^(-51)
float SqrtByBisection(float n){
    float low, up, mid, last;
    low = 0, up = (n < 1 ? 1 : n);
    mid = (low + up) / 2;
    do{
        if (mid * mid > n)up = mid;
        else low = mid;
        last = mid;
        mid = (low + up) / 2;
    } while (fabsf(mid - last) > eps);

    return mid;
}

这种方法非常直观,也是面试过程中经常会问到的问题,不过这里有一点需要特别注意:在精度判别时不能利用上下限而要利用前后两次mid值,否则可能会陷入死循环!这是因为由于精度问题,在循环过程中可能会产生mid值和up或low中的一个相同。这种情况下,后面的计算都不会再改变mid值,因而在达不到精度内时就陷入死循环。但是改为判断前后两次mid值就不会有任何问题(为啥自己想)。大家可以找一些例子试一下,这可以算是二分法中的一个trick。二分虽然简单,但是却有一个非常大的问题:收敛太慢!也即需要循环很多次才能达到精度要求。这也比较容易理解,因为往往需要迭代3到4次才能获得一位准确结果。为了能提升收敛速度,我们需要采用其它的方法。

牛顿迭代法

原理也比较简单,就是将中值替换为切线方程的零根作为最终解。原理可以利用下图解释:

牛顿迭代法求开方

这里写图片描述

#define eps 2^(-51)
float SqrtByNewton(float x){
    float val = x, last;
    do{
        last = val;
        val = (val + x / val) / 2;
    } while (fabsf(val - last) > eps);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值